2012-04-13 117 views
0

我意识到存在很多类似的问题,但找不到解决我的问题的任何问题(阅读:我没有真正理解答案,以便可以应用它以我的情况)带有模板化参数的模板化函数

我有以下功能:

void printVariable(map<string, bool*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

现在,如果我有一个map<string, bool*> mapping我可以做到以下几点:printVariable(mapping.begin());

这个工作,现在我也有AA map<string, int*>和希望能够做到同样的,所以我想我改变printVariable功能:

template <typename T> 
void printVariable(map<string, T*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

然而这使编译错误(GCC):

error: variable or field 'printVariable' declared void 
error: expected ')' before 'it' 

我想我可以解决此很容易通过重载函数。但我想知道为什么上述不起作用。

EDIT2:删除的文本声称一个合适的解决方案是错误的

+0

如果迭代器是模板类型上的依赖类型,是否需要向参数添加类型名说明符? 'void printVariable(typename map :: iterator it)' – 2012-04-13 12:31:29

回答

5

你要说typename来澄清对从属名称:

template <typename T> 
void printVariable(typename map<string, T*>::iterator it) 
//     ^^^^^^^^ 

但是,请注意,这不是一个可推断上下文,所以这种形式不是非常方便。

更重要的是,才使整个迭代器模板参数:

template <typename Iter> 
void printVariable(Iter it) 
{ /* ... */ } 

这样,你也可拍摄的地图,非标准比较器或分配器,和无序的地图,等等,等等


下面是一个简单的思考实验,说明为什么你在第一种情况下没有可推论的背景:T如何在foo的以下调用中推导出来?

template <typename T> void foo(typename Bar<T>::type); 

template <typename T> struct Bar { typedef char type; }; 
template <> struct Bar<int>  { typedef int type; }; 
template <> struct Bar<double> { typedef int type; }; 

foo(10); // What is T? 
+0

不,第一个变体不起作用。 – 2012-04-13 12:32:05

+0

第一个变体确实不起作用(我想我也已经试过了)。然而第二个变体可以工作!感觉很愚蠢,因为没有像这样的东西试试:) – user1302914 2012-04-13 12:43:25

+0

有人可以解释为什么第一个变种不起作用?我实际上更喜欢这个变体(如果它工作的话),因为那么函数签名对于函数参数应该是什么更清晰(或者我不应该考虑这样的事情?) – user1302914 2012-04-13 12:47:06