0
template<typename T>
struct Obj
{
    template<typename U>
    void m(){};
};

template<typename T>
void func()
{
    Obj<T> v;    // Obj<int> v; is compilable
    v.m<int>();
}

This piece of code gives me an error:

test.cpp: In function ‘void f()’:
test.cpp:21:9: error: expected primary-expression before ‘int’
     v.m<int>();
         ^
test.cpp:21:9: error: expected ‘;’ before ‘int’

However, if I change Obj<T> v; into Obj<int> v;, it will be compilable.

I don't know why.

Yves
  • 11,597
  • 17
  • 83
  • 180

1 Answers1

0

Use

v. template m<int>();

From the C++ 17 Standard (17.2 Names of template specializations )

4 The keyword template is said to appear at the top level in a qualified-id if it appears outside of a templateargument-list or decltype-specifier. In a qualified-id of a declarator-id or in a qualified-id formed by a class-head-name (Clause 12) or enum-head-name (10.2), the keyword template shall not appear at the top level. In a qualified-id used as the name in a typename-specifier (17.6), elaborated-type-specifier (10.1.7.3), using-declaration (10.3.3), or class-or-decltype (Clause 13), an optional keyword template appearing at the top level is ignored. In these contexts, a < token is always assumed to introduce a template-argument-list. In all other contexts, when naming a template specialization of a member of an unknown specialization(17.6.2.1), the member template name shall be prefixed by the keyword template

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335