All compilers I could get my hands on agree that this is fine:
template <typename Check, typename... T>
auto foo(Check, T...) -> void;
template <typename... T>
auto foo(int, T...) -> void;
int main()
{
foo(7, "");
}
However, the following code (with a leading template parameter that cannot be deduced from the function parameters) is ambiguous according to gcc:
template <typename X, typename Check, typename... T>
auto bar(Check, T...) -> void;
template <typename X, typename... T>
auto bar(int, T...) -> void;
int main()
{
bar<void>(7, ""); // ambiguous according to gcc
bar<void>(7); // just fine
}
On the other hand, clang, msvc and icc are quite happy with this.
Which compiler is right?
References to the respective sections of the standard preferred.
This is core issue 200.
The description of how the partial ordering of template functions is determined in 14.5.6.2 [temp.func.order] paragraphs 3-5 does not make any provision for nondeduced template parameters. For example, the function call in the following code is ambiguous, even though one template is "obviously" more specialized than the other:
template <class T> T f(int); template <class T, class U> T f(U); void g() { f<int>(1); }
The reason is that neither function parameter list allows template parameter
T
to be deduced; both deductions fail, so neither template is considered more specialized than the other and the function call is ambiguous.
The resolution of core issue 214, which this one was reduced to, introduced [temp.deduct.partial]/11:
In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering.
Apparently GCC's implementation of this wording is buggy once packs come into play.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With