Use the keyword template as a qualifier to distinguish member
templates from other names. The following example illustrates when you
must use template as a qualifier:
class A { public: template<class T> T function_m() { }; }; template<class U> void function_n(U argument) { char object_x = argument.function_m<char>(); }
The declaration char object_x = argument.function_m<char>(); is ill-formed. The compiler assumes that the < is a less-than operator. In order for the compiler to recognize the function template call, you must add the template quantifier:
char object_x = argument.template function_m<char>();
If the name of a member template specialization appears after a ., ->, or :: operator, and that name has explicitly qualified template parameters, prefix the member template name with the keyword template. The following example demonstrates this use of the keyword template:
#include <iostream> using namespace std; class X { public: template <int j> struct S { void h() { cout << "member template's member function: " << j << endl; } }; template <int i> void f() { cout << "Primary: " << i << endl; } }; template<> void X::f<20>() { cout << "Specialized, non-type argument = 20" << endl; } template<class T> void g(T* p) { p->template f<100>(); p->template f<20>(); typename T::template S<40> s; // use of scope operator on a member template s.h(); } int main() { X temp; g(&temp); }
The following is the output of the above example:
Primary: 100 Specialized, non-type argument = 20 member template's member function: 40
If you do not use the keyword template in these cases, the compiler will interpret the < as a less-than operator. For example, the following line of code is ill-formed:
p->f<100>();
The compiler interprets f as a non-template member, and the < as a less-than operator.
Related References