When deriving from a template base class, methods and attributes of the base class aren't immediately available, i.e if Base<T>
has a void Func()
, then Derived
deriving from Base<T>
has to call Base<T>::Func
and not merely Func
.
In Why must we specify template arguments for template base class when calling its constructor?, the following explanation is provided:
Injected class name are in the scope of the class. So are class member names. The general rule is that dependent base scope names are not visible at the point of definition of the derived template class. It is true that whatever T the injected class name of
Base<T>
isBase
so compilers could infer thatBase
designate the injected class name ofBase<T>
. But that would be an other special rule. My opinion is that the c++ language has enough corner cases, and special rules which hurts coherency. So I am glad to see there is no special treatment for dependent base class injected name. - Oliv
In CppCon 2020 Back to Basics: Templates (part 1 of 2), the subject is touched upon as well and explained with
The simple nature of that is that because there is not necessarily only one of these [Base], you can publicly or privately derive multiple times from Foo just with a different type [...]
Oliv's one explains well why we can't call Base::Func
, but if it also explains why we couldn't call Func
, that's not clear to me.
As for the explanation by the CppCon presenter, sure, we could derive from multiple Base
instantiations, but we don't. If A
and B
both have a void Func()
, then if I derive from A
, I can call Func
without specifying A::Func
. Only when I derive from A
and B
will the compiler understandably complain if I try to call Func
. I would expect the same behaviour for templates: only when we derive from Base<T>
and Base<U>
would we get an ambiguity error. Or from A
and Base<T>
for that matter.
Is there a reason for things not be this way that I'm not seeing there ?