6

As titled, why is the template instantiation in the main function wrong? I use Clang++ with flag "-std=c++2a". Did I use anything in a wrong way here?

template<int, int>
void f(int) { std::cout << "int"; };

template<class T> 
void g() {  // dependent-name.
  f<0, T()>(0);
}

int main() {
  g<int>();  // wrong here, why?
}

Error messages from Clang:

test.cc:41:3: error: no matching function for call to 'f'
  f<0, T()>(0);
  ^~~~~~~~~
test.cc:48:3: note: in instantiation of function template specialization 'g<int>' requested here
  g<int>(); // "int";
  ^
test.cc:35:6: note: candidate template ignored: invalid explicitly-specified argument for 2nd
      template parameter
void f(int) { std::cout << "int"; };
     ^
1 error generated.
cigien
  • 57,834
  • 11
  • 73
  • 112
Jason Yu
  • 1,886
  • 16
  • 26
  • 6
    `f<0, T{}>(0);` and `f<0, (T())>(0);` both work... Most-vexing parse in a template argument? Wow. – Quentin Aug 19 '20 at 15:11
  • 3
    gcc has a better message; "ambiguous template argument for non-type template parameter is treated as function type" – molbdnilo Aug 19 '20 at 15:13

1 Answers1

11

This instantiation:

f<0, T()>(0);

for T=int gives int() for the second explicit template parameter. This is basically a vexing parse, and so the argument is treated as a function type. This is not the same as an int object, which is what f expects for its template parameters.

Instead, you can instantiate it like this:

f<0, T{}>(0);

so that the second template parameter is an int object.

Here's a demo.

cigien
  • 57,834
  • 11
  • 73
  • 112