Consider this code:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
https://godbolt.org/z/Gc_w8i
This prints:
vector overload
int overload
Why does this not produce a compilation error due to ambiguous overload resolution? If the second constructor is removed, we get vector overload two times. How/by what metric is int an unambiguously better match for {} than std::vector<int>?
The constructor signature can surely be trimmed further, but I just got tricked by an equivalent piece of code and want to make sure nothing important is lost for this question.
It's in [over.ics.list], emphasis mine
6 Otherwise, if the parameter is a non-aggregate class X and overload resolution per [over.match.list] chooses a single best constructor C of X to perform the initialization of an object of type X from the argument initializer list:
If C is not an initializer-list constructor and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence has Exact Match rank if U is X, or Conversion rank if U is derived from X.
Otherwise, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
9 Otherwise, if the parameter type is not a class:
[...]
if the initializer list has no elements, the implicit conversion sequence is the identity conversion. [ Example:
void f(int); f( { } ); // OK: identity conversionend example ]
The std::vector is initialized by constructor and the bullet in bold deems it a user defined converison. Meanwhile, for an int, this is the identity conversion, so it trumps the rank of the first c'tor.
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