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
}
};