Consider the following example:
template <typename T>
class A {
private:
typedef typename T::C C;
};
template <typename T>
class B : public A<B<T>> {
public:
typedef T C;
};
int main() {
B<int> b;
}
Compiling it with GCC gives the following error:
test.cc:5:23: error: no type named 'C' in 'B<int>'
typedef typename T::C C;
~~~~~~~~~~~~^
test.cc:9:18: note: in instantiation of template class 'A<B<int> >' requested here
class B : public A<B<T>> {
^
test.cc:15:10: note: in instantiation of template class 'B<int>' requested here
B<int> b;
^
Why does compiler give an error if B::C
is defined and how to fix it?
At this point,
… class
B
is incomplete. ClassA
can't look inside it.The
C
type definition insideB
is accessible from that point insideB
, and on. It's also available inside function bodies inB
because you can regard a function definition inside the class definition as a shorthand for placing it after the class. But an incomplete class contains nothing as viewed from outside: all that outside code can do is form pointers and references and use the class as template argument.You can fix your code by changing the design. The most obvious is to pass the type as a separate template argument. But depending on what you're trying to achieve it may be that the inheritance you currently have, isn't really needed or even useful.