[英]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_obj
是std::map<int, int>
。 那么在第2行和第3行中,您还应该做什么? 只能实例化模板函数set
和show
用Table
= 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_type
和mapped_type
是std :: 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.