Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)).

like image 634
template boy Avatar asked Jan 18 '15 01:01

template boy


1 Answers

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.

like image 184
Columbo Avatar answered Oct 24 '22 08:10

Columbo