Why are members of a base class not available in a derived class if the base is templated in the derived?
At compile time all of the types should be instantiated, so I don't see what or why it is different. I can see an argument for this being able to create unresolvable types; but, that feels like a compile time error, not a restriction to the language.
More explicitly, why does this work?
template<typename T>
class A{
protected:
int member;
};
class B: public A<int>{
decltype(member) another_member;
};
But, this doesn't?
template<typename T>
class A{
protected:
int member;
};
template<typename T>
class B: public A<T>{
decltype(member) another_member;
};
CodePudding user response:
There is an ISOCPP FAQ for this question.
https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
and read the next one too about how it can silently hurt you
https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-silent-bug
Basically the compiler will not look into templated base classes. The reason is likely that the concrete class does not exist at that point.
The previous example works because A<int>
is a concrete class while A<T>
is not. For the same reason you are forced to add typename
to arguments and members.
You should put the scope back as in
decltype(A<T>::member)
or even (surprisingly)
decltype(B::member)