template boy
template boy

Reputation: 10490

Ambiguous function call with two parameter packs

The following compiles in clang but not in gcc:

template <class... Ts, class... Args>
void f(Ts&&..., Args&&...);

int main()
{
    f();
}

This is the error I get in GCC:

main.cpp: In function 'int main()':
main.cpp:30:7: error: no matching function for call to 'f()'
     f();
       ^
main.cpp:30:7: note: candidate is:
main.cpp:23:6: note: template<class ... Ts, class ... Args> void f(Ts&& ..., Args&& ...)
 void f(Ts&&..., Args&&...)
      ^
main.cpp:23:6: note:   template argument deduction/substitution failed:
main.cpp:30:7: note:   candidate expects 1 argument, 0 provided
     f();
       ^

If I give an argument like f(0) then it compiles with GCC but not with Clang.

Error with clang:

main.cpp:30:5: error: no matching function for call to 'f'
    f(0);
    ^
main.cpp:23:6: note: candidate function not viable: requires 0 arguments, but 1 was provided
void f(Ts&&..., Args&&...)
     ^
1 error generated.

If I give the same number of explicit template arguments as function parameters then it compiles with both compilers (i.e f<int, int, int>(0, 0, 0)).

Upvotes: 9

Views: 282

Answers (1)

Columbo
Columbo

Reputation: 61009

The second template parameter pack Args is indeed deduced:

A trailing template parameter pack (14.5.3) not otherwise deduced will be deduced to an empty sequence of template arguments.

Taking that into account it also becomes clear that e.g. f<int>(0) is well-formed. However, Ts is never deduced. [temp.deduct.call]/1:

When a function parameter pack appears in a non-deduced context (14.8.2.5), the type of that parameter pack is never deduced.

Note that the previous quote doesn't apply to Ts, as it isn't trailing. Therefore, pure deduction will always fail.

Upvotes: 2

Related Questions