3

The following code does not compile with gcc 6.4 in Debian Sid, due to the error: "typename is not allowed".

struct A
{
template <typename T,typename R> static R f(T x)
{
    return (R)x;
}
};
template <class FUNCTION,typename T,typename R> R func()
{
    return FUNCTION::f<T,R>(2);
}
int main()
{
    return func<A,int,double>();
}

Interestingly enough the following code does compile:

struct A
{
template <typename T> static T f(T x)
{
    return x;
}
};
template <class FUNCTION,typename T> T func()
{
    return FUNCTION::f(2.f);
}
int main()
{
    return func<A,float>();
}

I presume that the second code does compile because the argument of the function provides enough information for GCC to perform template substitution. However I do not understand why the first code fails to compile. So does anybody can explain me why?

fabian_mc
  • 33
  • 4

1 Answers1

3

You need to use keyword template to tell the compiler that the dependent name f (it depends on the template parameter FUNCTION) is a template name. Only when the compiler knows that's a template name it takes < as the beginning of template-argument-list, otherwise it will try to take < as the less-than operator.

e.g.

return FUNCTION::template f<T,R>(2);
//               ~~~~~~~~

The 2nd one works because you didn't use <> (to specify template arguments explicitly).

songyuanyao
  • 169,198
  • 16
  • 310
  • 405