Ошибка с T :: iterator, где параметр шаблона T может быть вектором <int>или списком <int> - PullRequest
6 голосов
/ 17 сентября 2010

Я пытаюсь написать функцию для вывода представления общих контейнеров STL (вектор, список и т. Д.).Я дал функции шаблонный параметр T, который, например, может представлять вектор.У меня проблемы с получением итератора типа T.

vector<int> v(10, 0);
repr< vector<int> >(v);

...

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        T::iterator i;
        for (i = v.begin(); 
             i != v.end()-1;
             ++i)
        {
            cout << *i << ", ";
        }
        cout << *(++i) << ' ';
    }
    cout << "]\n";
}

...

brett@brett-laptop:~/Desktop/stl$ g++ -Wall main.cpp
main.cpp: In function ‘void repr(const T&)’:
main.cpp:13: error: expected ‘;’ before ‘i’
main.cpp:14: error: ‘i’ was not declared in this scope
main.cpp: In function ‘void repr(const T&) [with T = std::vector<int, std::allocator<int> >]’:
main.cpp:33:   instantiated from here
main.cpp:13: error: dependent-name ‘T::iterator’ is parsed as a non-type, but instantiation yields a type
main.cpp:13: note: say ‘typename T::iterator’ if a type is meant

Я пытался 'typename T:: iterator ', как предложил компилятор, но получил только более загадочную ошибку.

Редактировать: Спасибо за помощь, ребята!Вот рабочая версия для тех, кто хочет использовать эту функцию:

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        typename T::const_iterator i;
        for (i = v.begin(); 
             i != v.end();
             ++i)
        {
            if (i != v.begin())
            {
                cout << ", ";
            }
            cout << *i;
        }
        cout << ' ';
    }
    cout << "]\n";
}

Ответы [ 2 ]

18 голосов
/ 17 сентября 2010

Вам нужно typename, чтобы сообщить компилятору, что ::iterator должен быть типом. Компилятор не знает, что это тип, потому что он не знает, что такое T, пока вы не создадите экземпляр шаблона. Это может также относиться к некоторому статическому члену данных, например. Это твоя первая ошибка.

Ваша вторая ошибка в том, что v является ссылкой на const . Таким образом, вместо ::iterator вы должны использовать ::const_iterator. Вы не можете запросить постоянный контейнер для неконстантного итератора.

3 голосов
/ 17 сентября 2010

Измените T::iterator i; на typename T::const_iterator i;, поскольку ::iterator относится к типу T, а v - это const &.

Перед квалифицированным зависимым типом необходимо typename.Без typename существует правило синтаксического анализа C ++, которое гласит, что квалифицированные зависимые имена должны быть проанализированы как non-types, даже если это приводит к синтаксической ошибке.

typename гласит, что следующее имя должно бытьрассматривается как тип.В противном случае имена интерпретируются как относящиеся к не типам.

...