0

The following code fails to compile both on g++ and clang++ with different error messages. In particular, it is the second line of main which triggers an error.

I do not understand why, as there is nothing ambiguous. The function has two arguments, which means that the template pack must have exactly two arguments, and all types are duly explicitly specified.

Any explanation?

#include <iostream>
enum A {A1,A2};
template <typename...Ts, A a=A2>
void foo(Ts...ps) { (std::cout << ... << ps); }

int main()
{
    foo<int,int>(1,2);     // this compiles
    foo<int,int,A2>(1,2);  // this does not compile
    return 0;
}
Fabio
  • 2,105
  • 16
  • 26
  • Substituting explicit template arguments happens before anything is deduced from function arguments. I'm not sure what weird corner cases would come up if we tried imagining a change to those rules that might cover this. – aschepler Mar 08 '19 at 12:13

1 Answers1

1

Variadic template arguments are greedy, so if you try and explicitly specify the template arguments for a template that has a variadic argument, once the explicit arguments start being allocated to the variadic pack, all remaining arguments are allocated to that pack. In this case A2 is not a type, so when the compiler tries to allocate it to the Ts... pack, it causes an error.

You could overload your template, allowing the enum to be specified as the first parameter:

template <A a,typename...Ts >
void foo(Ts...ps) { std::cout << sizeof...(ps); }
template <typename...Ts>
void foo(Ts...ps) { foo<A2>(ps...); }

foo<int,int>(1,2);     // this compiles
foo<A2,int,int>(1,2);  // this compiles
Anthony Williams
  • 66,628
  • 14
  • 133
  • 155