e.J*_*mes 2 c++ templates iterator stl compiler-errors
我在类模板中使用私有std :: map变量时遇到问题.任何人都可以解释为什么以下(简化示例)不起作用,以及我应该做什么呢?
#include <iostream>
#include <map>
template <class T>
class Container
{
private:
typedef std::map<long, T> Map;
typedef Map::iterator Iterator; // <-- this is line 10
Map items;
public:
void insert(const long id, const T& item) { items[id] = item; }
void print()
{
for (Iterator iter = items.begin(); iter != items.end(); iter++)
{ std::cout << iter->second << std::endl; }
}
};
int main()
{
Container<int> container;
container.insert(300, 1);
container.insert(200, 2);
container.insert(100, 3);
container.print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产生的错误有点神秘:
t.cpp:10:错误:类型'std :: map,std :: allocator >>'不是从'Container'类型派生的
t.cpp:10:错误:ISO C++禁止声明没有类型的'iterator'
t.cpp:10:错误:预期';' 在"Iterator"之前
您需要限定依赖类型名称:
typedef typename Map::iterator Iterator;
Run Code Online (Sandbox Code Playgroud)
基本原理:在解析模板时,编译器无法确定是类型还是值表达式.这是因为名称取决于模板参数,这些参数仅在实例化时知道.
你必须帮助编译出来.
图片的标题说明:
MSVC似乎对此规则不严格,因为它的模板实例化引擎以非标准方式运行,并且直到实例化时间才进行名称查找
有时,依赖成员模板也需要合格:
template <typename aTuple> struct ContrivedSample
{
aTuple data;
void foo()
{
auto v = data.template get<0>(); // template required
}
};
Run Code Online (Sandbox Code Playgroud)