如何在模板化的类中使用std :: map迭代器?

时间:2011-11-30 21:45:09

标签: c++ templates stl iterator 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;
}

由此产生的错误有点神秘:

  

t.cpp:10:错误:输入'std :: map,std :: allocator&gt; &GT;”不是从“容器”类型派生的

     

t.cpp:10:错误:ISO C ++禁止声明没有类型的'iterator'

     

t.cpp:10:错误:预期';'在“Iterator”之前

1 个答案:

答案 0 :(得分:8)

您需要限定依赖 typename:

    typedef typename Map::iterator Iterator;

原理:编译器在解析模板时无法确定是类型还是表达式。这是因为名称取决于模板参数,这些参数仅在实例化时知道。

你必须帮助编译出来。


图片的标题说明:

  • MSVC似乎对此规则不严格,因为它的模板实例化引擎以非标准方式运行,并且直到实例化时间才进行名称查找

  • 有时,依赖成员模板也需要合格:

    template <typename aTuple> struct ContrivedSample
    {
        aTuple data;
    
        void foo()
        {
           auto v = data.template get<0>(); // template required
        }
    };