我意识到有很多类似的问题,但我找不到任何可以解决我的问题(阅读:我没有真正理解答案,以便我可以将它应用到我的案例中)
我有以下功能:
void printVariable(map<string, bool*>::iterator it)
{
cout << it->first << " " << *(it->second) << endl;
}
现在,如果我有map<string, bool*> mapping
我可以执行以下操作:printVariable(mapping.begin());
这个有效,现在我也有一个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 :(得分: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?
?
{{1}}