Consider the following contrived piece of code:
template <class... > struct pack { };
template <class R, class T, class... Args>
int foo(pack<T>, Args...)
{
return sizeof(R);
}
template <class R, class T, class... Ts, class... Args>
int foo(pack<T, Ts...>, Args... args)
{
return foo<T>(pack<Ts...>{}, args...);
}
int main() {
// gcc: OK, clang: ambiguous
foo<int>(pack<int>{});
// gcc: ambiguous, clang: ambiguous
foo<int>(pack<int>{}, 0);
}
Both gcc and clang accept both calls if the 2nd overload is changed to take a pack of at least 2 types instead of a pack of at least one type:
template <class R, class T, class T2, class... Ts, class... Args>
int foo(pack<T, T2, Ts...>, Args... args)
{
return foo<T>(pack<T2, Ts...>{}, args...);
}
If the non-deduced template parameter is moved to a deduced template parameter, then:
template <class... > struct pack { };
template <class R, class T, class... Args>
int foo(pack<R>, pack<T>, Args...)
{
return sizeof(R);
}
template <class R, class T, class... Ts, class... Args>
int foo(pack<R>, pack<T, Ts...>, Args... args)
{
return foo(pack<T>{}, pack<Ts...>{}, args...);
}
int main() {
// gcc ok with both, clang rejects both as ambiguous
foo(pack<int>{}, pack<int>{});
foo(pack<int>{}, pack<int>{}, 0);
}
I'd expect all the calls to be OK in every version of this. What is the expected outcome of the above code examples?