Search code examples
c++templatestypedeficc

How can you extract typedef'd information from a class that is inherited through templates?


I have a question about extracting typedef'd information from a class inherited through templates. To illustrate my question, consider the following simple example:

#include <iostream>

class A1{
public:
    void print(){ printf("I am A1\n"); };
};
class A2{
public:
    void print(){ printf("I am A2\n"); };
};

class B1{
public:
    typedef A1 A;
};

class B2{
public:
    typedef A2 A;
};

template<class b>
class C{
    typedef class b::A AA;
    AA a;
public:
    void Cprint() {     a.print();  };
};

int main()
{
    C<B1> c1;
    c1.Cprint();

    C<B2> c2;
    c2.Cprint();
}

Class C takes a class (either B1 or B2) as a template parameter. Both B1 and B2 have a tyepdef called A (which is class A1 and A2, respectively). At compile time, class C should be able to figure out which of the two "A" classes is being used by the "B" class. When I compile with g++, the above code works perfectly. However, when I compile it with Intel's icpc, I get the following error:

test.cpp(24): error: typedef "A" may not be used in an elaborated type specifier
    typedef class b::A AA;
                     ^
    detected during instantiation of class "C<b> [with b=B1]" at line 33

Is there another way to achieve a similar effect? Of course, my actual code is much more complicated and there are reasons I want the classes structured in this way. There are also reasons I want to compile with icpc and not g++.

Thanks in advance. Carl


Solution

  • Try changing:

    template<class b>
    class C{
        typedef class b::A AA;
        AA a;
    public:
        void Cprint() {     a.print();  };
    };
    

    to:

    template<class b>
    class C{
        typedef typename b::A AA;
        AA a;
    public:
        void Cprint() {     a.print();  };
    };
    

    b::A is a dependent type (it is dependent on what type is used for b).

    FYI, the original posted code failed to compile with VS2008 and VS2010.