繁体   English   中英

编译器如何从map中找出模板类型

[英]how did the compiler figure out the template types from map

我是一个胆小的用户,使用模板,通常遵循例行案例。

因此,我很惊讶地看到以下代码。

template<typename Table> void set(Table& tbl,
const typename Table::key_type& key,
const typename Table::mapped_type& attr)
{
  typename Table::iterator iter = tbl.find(key);
  if (iter != tbl.end()) {
    iter->second = attr;
  } else {
    typedef typename Table::key_type TableKey;
    typedef typename Table::mapped_type TableNonKey;
    tbl.insert( std::pair<TableKey,TableNonKey>(key,attr) );
  }
}

template<typename Table> void show(Table& tbl)
{
  for (typename Table::iterator iter = tbl.begin();
    iter != tbl.end(); ++iter) {
    cout << iter->second << endl;
  }
}

int main(){
  std::map<int, int> table_obj;
  set(table_obj, 1, 2);
  show(table_obj);
}

当涉及到编译show / set函数时,编译器如何知道Table是std :: map并能够从中扣除Table :: key_type和Table :: mapped_type? 模板还有其他类似的用例吗?

您的代码:

  std::map<int, int> table_obj;
  set(table_obj, 1, 2);
  show(table_obj);

你的问题:

当涉及到编译show / set函数时,编译器如何知道Table是std :: map并能够从中扣除Table :: key_type和Table :: mapped_type?

答:因为table_obj的类型是已知的。

只需将自己放在编译器的位置即可。 在第1行中,您看到table_objstd::map<int, int> 那么在第2行和第3行中,您还应该做什么? 只能实例化模板函数setshowTable = std::map<int, int> 没有歧义。

如果尝试用其他类型实例化函数,则会发生错误:

set<double>(table_obj, 1, 2);                    // error
set<void>(table_obj, 1, 2);                      // error
set<std::map<int *, char *> >(table_obj, 1, 2);  // error
set<std::map<double, int> >(table_obj, 1, 2);    // error
set<std::map<int, int> >(table_obj, 1, 2);       // OK

如您所见,指定类型是多余的 因此,C ++允许您忽略它。

这种语言的特征称为模板参数推导


模板还有其他类似的用例吗?

几乎每次都使用标准算法。

考虑以下示例:

#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> v;
    std::find(v.begin(), v.end(), 123);
}

如果没有模板参数推导,则最后一行必须写为:

int main()
{
    std::vector<int> v;
    std::find<std::vector<int>::iterator, int>(v.begin(), v.end(), 123);
}

main编译器知道“表”的类型,然后使用Koenig查找 / ADL找到一个合适的set在这种情况下,琐屑因为只有一个。

宣言

template<typename Table> void set(Table& tbl,
const typename Table::key_type& key,
const typename Table::mapped_type& attr);

履行

template<typename Table> void set(Table& tbl,
const typename Table::key_type& key,
const typename Table::mapped_type& attr) {
  typename Table::iterator iter = tbl.find(key);
  if (iter != tbl.end()) {
    iter->second = attr;
  } else {
    typedef typename Table::key_type TableKey;
    typedef typename Table::mapped_type TableNonKey;
    tbl.insert( std::pair<TableKey,TableNonKey>(key,attr) );
  }
}

key_typemapped_typestd :: map的 typedef。

如果您这样称呼“设置”

std::vector<int> NotAMap;
set(NotAMap, 1, 2);

循环仍然会找到'set',开始时发现Table可能是std :: vector,但是std :: vector没有mapped_type因此被拒绝作为候选对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM