I have the following code in a project I am doing for class. I have been having trouble with the print statement for hours, and I could not find what I needed on the internet.
Here is my templated class definition:
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;
}
....
};
Then the problem I'm having is in print:
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;
}
When I try to compile with g++ I get the following error message:
oset.cc:276: error: expected primary-expression before ‘>’ token
oset.cc:276: error: ‘i’ was not declared in this scope
The problem is in the commented line. The '>' token giving problems is the one directly before the first i
. For some reason it does not like the <S>
. If i get rid of the <S>
it tells me it expects a ';' before the i
I honestly have no idea what is causing the problem. I am getting very frustrated and any help would be highly appreciated. Thanks!
for (oset<S>::iter<S> i = OS.begin(); i != OS.end(); ++i) { //error this line
You've to use typename
and template
here:
for (typename oset<S>::template iter<S> i = OS.begin(); i != OS.end(); ++i)
Note that none of the following would work:
oset<S>::iter<S> i //error
typename oset<S>::iter<S> i //error
oset<S>::template iter<S> i //error
Your situation is such that you've to use both keywords : typename
as well as template
:
typename oset<S>::template iter<S> i //ok
Why you need both keywords here, is explained by @Johannes in this topic:
T
wherever you're using U
in its definition.iter
to iterator
. Make it look like standard container/iterator, so that you could use it in agorithms defined in <algorithm>
.That is, your class should look like this:
class iterator {
node<T> *pos;
iterator(node<T>* n) : pos(n) { }
friend class oset<T>;
};
Then in for
loop, you would only need typename
as:
typename oset<S>::iterator i //ok
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With