Reputation: 189
can anyone suggest why this does not compile? I guess I'm missing something major here. The compiler is g++ 4.2.1 (on OS X) and error is "expected `;' before ‘it’" on the line where the iterator is declared.
#include <vector>
template <class T>
class A {
public:
struct SomeStruct {
T* ptr;
int i;
};
typedef std::vector<SomeStruct> MyList;
void Func()
{
MyList::iterator it;
}
};
Upvotes: 1
Views: 209
Reputation: 44344
Change:
MyList::iterator it;
to:
typename MyList::iterator it;
I believe this has to do with the compiler not being sure as to whether MyList::iterator
should be a value of some sort (say that iterator
was a static member of MyList
) or a type. typename
forces the latter (correct) option.
I believe the relevant standard quoting starts here, second 14.6:
A name used in a template is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword
typename
.
So, you'd have to figure out what the "applicable name lookup" is, but the standard also follows up with this example:
// no B declared here
class X;
template<class T> class Y {
class Z; // forward declaration of member class
void f() {
X* a1; // declare pointer to X
T* a2; // declare pointer to T
Y* a3; // declare pointer to Y<T>
Z* a4; // declare pointer to Z
typedef typename T::A TA;
TA* a5; // declare pointer to T’s A
typename T::A* a6; // declare pointer to T’s A
T::A* a7; // T::A is not a type name:
// multiply T::A by a7
B* a8; // B is not a type name:
// multiply B by a8; ill-formed,
// no visible declaration of B
}
};
Upvotes: 6
Reputation: 145429
You're lacking a typename
:
#include <vector>
template <class T>
class A {
public:
struct SomeStruct {
T* ptr;
int i;
};
typedef std::vector<SomeStruct> MyList;
void Func()
{
typename MyList::iterator it;
}
};
int main() {}
This code compiles with g++, msvc and Comeau Online.
Technically SomeStruct
is a dependent name, meaning that what SomeStruct
stands for depends on the template parameter. From the compiler's point of view std::vector
might be specialized for some A<T>::SomeStruct
, where that specialization doesn't have an iterator
typedef. So you have to tell the poor compiler. ;-)
Cheers & hth.,
Upvotes: 4