template<class T>
T::type<int> f(){
}
According to [temp.names#3.4]
A < is interpreted as the delimiter of a template-argument-list if it follows a name that is not a conversion-function-id and
- [...]
- that is a terminal name in a using-declarator ([namespace.udecl]), in a declarator-id ([dcl.meaning]), or in a type-only context other than a nested-name-specifier ([temp.res]).
According to [temp.res#general-4.3.1], T::type<int>
does satisfy the above rule(emphasized mine) due to the following rule
A qualified or unqualified name is said to be in a type-only context if it is the terminal name of
- [...]
- a decl-specifier of the decl-specifier-seq of a
- [...]
- simple-declaration or a function-definition in namespace scope,
T::type<int>
is the decl-specifier of the function-definition for template function f
that is in the namespace scope, hence the terminal name type
is said to be in the type-only context.
Also, according to [temp.res#general-5]
A qualified-id whose terminal name is dependent and that is in a type-only context is considered to denote a type.
Hence, the symbol <
in T::type<int>
is interpreted as the delimiter of the template-argument-list due to [temp.names#3.4] while the qualified-id T::type<int>
is considered to denote a type due to [temp.res#general-5], the example should be legal. However, it has been rejected by both Clang and GCC.
I wonder, Are both the keyword typename
and template
not necessary in this example compiled by future implementations?