Как я могу использовать итератор std :: map внутри шаблонного класса? - PullRequest
2 голосов
/ 01 декабря 2011

У меня проблемы с использованием закрытой переменной 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.cpp: 10: ошибка: ISO C ++ запрещаетобъявление 'iterator' без типа

t.cpp: 10: ошибка: ожидается ';'перед "Итератором"

1 Ответ

8 голосов
/ 01 декабря 2011

Вам необходимо указать имя typename:

    typedef typename Map::iterator Iterator;

Обоснование: компилятор во время анализа шаблона не может определить, является ли выражение type или value . Это связано с тем, что имена зависят от аргументов шаблона, которые известны только во время создания экземпляра.

Вы должны помочь компилятору.


Sidenotes:

  • MSVC кажется неэффективным с этим правилом, поскольку его механизм создания шаблонов ведет себя нестандартным образом, и поиск имен не выполняется до момента создания экземпляра в любом случае

  • иногда необходимо указывать шаблоны зависимых членов:

    template <typename aTuple> struct ContrivedSample
    {
        aTuple data;
    
        void foo()
        {
           auto v = data.template get<0>(); // template required
        }
    };
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...