Why isn't `typename` required for a base class that is a nested type?

Why isn't typename required in front of T::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 names

In 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.


You only need to use typename if you need to tell the compiler to expect a type rather than something else.

Since only a type can be inherited from, there is no ambiguity, and so typename is superfluous.