I've been very surprised to see that it is not necessary to add typename
when a dependent type appears as a base class:
struct B {}; struct wr { typedef B type; }; template<class T> struct A : T::type {}; int main() { A<wr> a; (void)a; }
Why isn't typename
required in front of T::type
?
Why isn't
typename
required in front ofT::type
?
Because you cannot inherit from a value. You use typename
to tell the compiler that a given nested identifier is a type, but for inheritance, that must be the case anyhow so you can omit it - that's why the language provides an exception to the typename
- rule for base-specifiers. From cppreference (emphasis mine):
The
typename
disambiguator for dependent namesIn a declaration or a definition of a template, including alias template, a name that is not a member of the current instantiation and is dependent on a template parameter is not considered to be a type unless the keyword typename is used or unless it was already established as a type name, e.g. with a typedef declaration or by being used to name a base class.
Note that we will get more places where typename
can be omitted, see P0634.
It's a special case, as others noted. To quote the standard on this:
[temp.res]
5 A qualified name used as the name in a class-or-decltype or an elaborated-type-specifier is implicitly assumed to name a type, without the use of the typename keyword. In a nested-name-specifier that immediately contains a nested-name-specifier that depends on a template parameter, the identifier or simple-template-id is implicitly assumed to name a type, without the use of the typename keyword. [ Note: The typename keyword is not permitted by the syntax of these constructs. — end note ]
And come C++20, there will be be even more exceptions to the need for typename
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With