More obscure places to find the template keyword Thursday 26th July 2007
Consider the following ill-formed c++ code:
class A { public: template< class U > U f(); }; template< class T , class U > class B { public: T g() { // error: expected primary-expression before ‘>’ token return u.f< T >(); } private: U u; }; template<> int A::f<int>() { return 0; } int main() { B< int, A > b; return b.g(); }
The class template B is “obviously” designed for use with a class (such as class A) which has a member function template f()
which takes no parameters. Because the template argument for f
cannot be deduced, we need to explicitly provide it with the f<type>
syntax. However, if we try to do that, as f
is dependent on the template argument U of B, the compiler cannot deduce whether f
is a template type or not. If not, the token < really could just mean “less”. In order to disambiguate this the template keyword must be used in definition of B::g
thus:
template< class T , class U > class B { public: T f() { return u.template f< T >(); } private: U u; };
A lot of compilers accept the ill-formed code without the template keyword, so you might not have noticed this. Fortunately most compilers do accept the correct code as well, so there should be no reason not to be correct.
Note that it is illegal to use the template keyword in this context (member function specifier) outside of a template declaration. Outside of a template definition there are no dependent types so the compiler can always resolve whether an identifier refers to a template or a non-template, so there can be no ambiguity.