template member function of template class called from template function

This doesn't compile:

template<class X> struct A {
   template<int I> void f() {}
};

template<class T> void g()
{
   A<T> a;
   a.f<3>();  // Compilation fails here (Line 18)
}

int main(int argc, char *argv[])
{
   g<int>();  // Line 23
}

The compiler (gcc) says:

hhh.cpp: In function 'void g()':

hhh.cpp:18: error: expected primary-expression before ')' token

hhh.cpp: In function 'void g() [with T = int]':

hhh.cpp:23: instantiated from here

hhh.cpp:18: error: invalid use of member (did you forget the '&' ?)

Can anyone explain why this is? Is there a way to get it to work?


Solution 1:

Try the following code:

template<class T> void g()
{
   A<T> a;
   a.template f<3>();  // add `template` keyword here
}

According to C++'03 Standard 14.2/4:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

Future C++ Standard seems to be still require this keyword according to draft n2857 14.3/4. Some compilers has special mode that allows to compile original code without errors (Comeau compiles it in so called relaxed mode).