Ошибка с t :: iTerator, где параметр шаблона t может быть вектор или список
Вопрос
Я пытаюсь написать функцию для печати представления общих контейнеров 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";
}
Решение
Тебе нужно typename
сказать компилятору, что ::iterator
Предполагается, что это тип. Компилятор не знает, что это тип, потому что он не знает, что это, пока вы не создаете шаблон. Это также может относиться к некоторым статическим элементе данных. Это ваша первая ошибка.
Ваша вторая ошибка в том, что v
это ссылка наконститут. Отказ Итак, вместо ::iterator
Вы должны использовать ::const_iterator
. Отказ Вы не можете задать постоянный контейнер для не-постоянного итератора.
Другие советы
Изменять T::iterator i;
к typename T::const_iterator i;
потому что ::iterator
имеет тип T
а также v
это const &
.
До квалифицированного типа зависимого вам нужно typename
Отказ Без typename
, существует правило разборки C ++, которое говорит, что квалифицированные имен должны быть проанализированы как non-types
Даже если это приводит к синтаксической ошибке.
typename
утверждает, что название, которое следует, следует рассматривать как тип. В противном случае имена интерпретируются для ссылки на не типы.