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

How can I use a std::map iterator inside a templated class?

本文关键字:std map 迭代器      更新时间:2023-10-16

我在类模板中使用私有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>>'不是从类型'Container'派生的

t.cp:10: error: ISO c++禁止声明没有类型

的'iterator'

t.p:10: error: expected ';' before "Iterator"

您需要限定依赖 typename:

    typedef typename Map::iterator Iterator;

理由:编译器在解析模板时,无法判断它是类型还是表达式。这是因为名称依赖于模板参数,而这些参数只有在实例化时才知道。

你必须帮助编译器。


旁注:

  • MSVC似乎对这条规则很宽松,因为它的模板实例化引擎以非标准的方式运行,并且直到实例化时间才完成名称查找

  • 有时候,依赖成员模板也需要被限定:

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