1

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;
    }
};
sbi
  • 219,715
  • 46
  • 258
  • 445
Emil Kirichev
  • 189
  • 10

2 Answers2

6

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
        }
};
Thanatos
  • 42,585
  • 14
  • 91
  • 146
  • No, `typename` is **not** required here! – Armen Tsirunyan Oct 26 '10 at 14:39
  • 1
    @Armen Tsirunyan: I compiled his code locally before posting this: The addition of `typename` fixes the compiler error ("expected `;' before ‘it’") – Thanatos Oct 26 '10 at 14:40
  • @Thanatos, @Alf: Apparently I was wrong but I still don't get it how SomeStruct is a dependent name... – Armen Tsirunyan Oct 26 '10 at 14:48
  • @Armen: depending on the `t` in `A::SomeStruct`, the `SomeStruct` is a different type. Concretely, in one case it's a struct that contains an `int` pointer, say, and in another it contains a `double` pointer, so on. But what matters is that `std::vector` (from the compiler's point of view, it's not practically possible!) might be specialized for one of those variants. Where that specialization might not have the `iterator` type member, or might have some other kind of member named `iterator`. Now I can't see any example where that could actually happen. But it's from general rules. Cheers, – Cheers and hth. - Alf Oct 26 '10 at 15:01
  • @Thanatos: re your last edit, it has nothing to do with whether `SomeStruct` is recognized as a type. It is recognized as a type. The code requires a `typename` keyword because the specialization of `vector` depends on `SomeStruct` which depends on the template parameter `T`. I.e. we're talking about *dependent names* here. As I recall there's a FAQ item about just that, if so good starting point. Cheers, – Cheers and hth. - Alf Oct 26 '10 at 15:08
  • @Alf: Thanks, I got it now :) – Armen Tsirunyan Oct 26 '10 at 15:31
4

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.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331