Can compile in MSVS, but cannot compile in GCC



  • Hello!

    Here is my code:

    template<class T> class Test1;
    template<class T> class Test2;
    
    template<class T> class Test1
    {
    public:
      typedef Test2<T> *myPointer;
    };
    
    template<class T> class Test2: Test1<T>
    {
      myPointer intPointer;
    };
    
    int main()
    {
      Test2<int> x;
      return 0;
    }
    

    Error is «myPointer does not name a type».
    What I am doing wrong?



  • Yes, your Code is wrong. But GCC tells you what to do

    foo.c++:12: error: ‘myPointer’ does not name a type
    foo.c++:12: note: (perhaps ‘typename Test1<T>::myPointer’ was intended)
    

    (see the note comment)

    template<class T> class Test1;
    template<class T> class Test2;
    
    template<class T> class Test1
    {
    public:
      typedef Test2<T> *myPointer;
    };
    
    template<class T> class Test2: Test1<T>
    {
      typename Test1<T>::myPointer intPointer;
    };
    
    int main()
    {
      Test2<int> x;
      return 0;
    }
    


  • the problem is that myPointer is a dependent name that needs to be qualified and marked as a typename, like ruediger showed. Imagine the following specialization of Test1:

    template<class T> class Test1
    {
    public:
      typedef Test2<T> *myPointer; //ok, so normally myPointer is a type
    };
    
    template<> class Test1<int>
    {
    public:
      int* myPointer; //ouch, here myPointer is a member variable!
    };
    
    template<class T> class Test2: Test1<T>
    {
      myPointer intPointer; //so what is myPointer here?
    };
    

    because the compiler cannot know what the "member" myPointer of Test1<T> really is, it assumes it to be a member variable or function. Therefore the need for the typename keyword. In addition,the compiler cannot know where the name myPointer should come from. Test1<T> is still a template that is not instantiated during the first pass through the code, the compiler simply doesnt know which names are inherited from there and considers myPointer an error. Therefore you need to tell him explicitly where that name comes from by qualifying it.



  • I know. I have read the note.

    The problem is that I have big project where similar errors are everywhere, even if the member (or type) is declared in the same class (not in its ancestor).

    I am asking for the explanation of this effect.

    Update: thank you, pumuckl.



  • Is there any way to say GCC compiler to instantiate templates (to analyse their code) only in cases of their use (as in MSVS)? I think this way the compiler will know values of template parameters, and such problems will not occur.



  • SAn schrieb:

    Is there any way to say GCC compiler to instantiate templates (to analyse their code) only in cases of their use (as in MSVS)? I think this way the compiler will know values of template parameters, and such problems will not occur.

    This ist no error in gcc, and IIRC it's not about the instantiation. The Compiler passes two times through the template code, where the first time is mainly about syntax checking and some name lookup and here the error occurs. The standard says it is an error, so gcc complains about it (and is right about that, imho). AFAIK, MSVC is a bit lazy in that first phase and thus does not see the error, because in the second phase the base class template has already been instantiated and therefore the name is already known and everything is fine.


Anmelden zum Antworten