Проблема с шаблонами в C++: "ожидаемое первичное выражение перед токеном`>'"
у меня есть следующий код в проект, я делаю для класса. У меня были проблемы с печатью заявления в течение нескольких часов, и я не мог найти то, что мне нужно в интернете.
вот мое определение шаблонного класса:
template <class T>
class oset {
template <class U>
class node {
.....
};
.....
public:
template <class U>
class iter {
node<U> *pos; // node _before_ the one with this->operator*
// constructor is private:
iter(node<U>* n) : pos(n) { }
friend class oset<U>;
....
};
private:
iter<T> start; // initialized in the constructors below
iter<T> finish; // initialized in the constructors below
public:
iter<T> begin() {
return start;
}
iter<T> end() {
return finish;
}
....
};
тогда проблема, с которой я сталкиваюсь, в печати:
template <class S>
void print(oset<S>& OS) {
for (oset<S>::iter<S> i = OS.begin(); i != OS.end(); ++i) {
// ^-- error is on previous line
cout << *i << " ";
}
cout << endl;
}
когда я пытаюсь скомпилировать с g++, я получаю следующее сообщение об ошибке:
oset.cc: 276: ошибка: ожидаемое первичное выражение перед ‘>’ токен
oset.cc: 276: error:’ i ' не был объявлен в этой области
проблема в закомментированную строку. Маркер">", дающий проблемы, находится непосредственно перед первым i
. По какой-то причине ему не нравится <S>
. Если я избавлюсь от <S>
Он говорит мне, что ожидается ';' перед i
Я честно понятия не имею, что вызывает проблему. Я очень расстроен, и любая помощь будет высоко оценена. Спасибо!
1 ответов
for (oset<S>::iter<S> i = OS.begin(); i != OS.end(); ++i) { //error this line
вы должны использовать typename
и template
здесь:
for (typename oset<S>::template iter<S> i = OS.begin(); i != OS.end(); ++i)
обратите внимание, что ни одно из следующих действий не будет работать:
oset<S>::iter<S> i //error
typename oset<S>::iter<S> i //error
oset<S>::template iter<S> i //error
ваша ситуация такова, что вы должны использовать оба ключевых слова : typename
а также template
:
typename oset<S>::template iter<S> i //ok
почему вам нужны оба ключевых слова здесь, объясняется @Johannes в этой теме:
несколько советов и улучшений
- сделать итератор не шаблон. Использовать
T
везде, где вы используетеU
в своем определении. - переименовать класс
iter
toiterator
. Сделайте его похожим на стандартный контейнер / итератор, чтобы вы могли использовать его в агорифмах, определенных в<algorithm>
.
то есть, ваш класс должен выглядеть это:
class iterator {
node<T> *pos;
iterator(node<T>* n) : pos(n) { }
friend class oset<T>;
};
затем в for
loop, вам понадобится только typename
as:
typename oset<S>::iterator i //ok