Use of typename keyword with template function parameters

If you slightly change your declaration, you get an entire different story

template <class T>
void foo(T::type& v);

That isn’t unambiguous anymore. It could declare a variable of type void that is initialized by a bit-wise AND expression. The entire declaration would be templated. Of course, this semantically is all nonsense, but it syntactically is alright.

The appearance of a single const syntactically makes it unambiguous, but it’s too much context dependence to make this work in a compiler. It has to remember that it read a const or any other such thing, and when it parses the T::type after it will need to remember to take this name as a type. It would also further bloat the already complicated Standard beyond belief.

Let’s again change your function declaration

template <class T>
void foo(const T::type);

Not even the appearance of const in there provides for a unambiguous parse. Should it be a function declaration with an unnamed parameter, or should it be a function declaration with an invalid parameter name that misses its type? A parameter’s name is parsed by a declarator-id, which can also be a qualified name. So here, the const will belong to the type specifiers, while the T::type will be parsed by the compiler as the name of the parameter, in absence of a typename. That is totally nonsense too, but is syntactically valid.

In the case of base-class names name lookup itself states that non-type names are ignored. So you get omission of typename for free: The name that name lookup yields to more higher level modules of the compiler either refers to a type, or name lookup will have given an error.

I have written a FAQ entry about Where and why do I have to put the “template” and “typename” keywords?.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)