Consider this snippet:
#include <iostream>
#include <vector>
void f(std::vector<int>){std::cout << __PRETTY_FUNCTION__ << '\n';}
void f(int x){std::cout << __PRETTY_FUNCTION__ << '\n';}
int main()
{
f({42});
}
Live on Coliru
If you run it, you can see that the f(int)
overload was preferred, even though std::vector
has an std::initializer_list
constructor (see #8).
Question: Why is the conversion {42}
to int
preferred (instead of conversion to std::vector
, as {42}
is an std::initializer_list
)?
In overload resolution, when considers implicit conversion sequence in list-initialization,
(emphasis mine)
Otherwise, if the parameter type is not a class and the initializer list has one element, the implicit conversion sequence is the one required to convert the element to the parameter type
Given f({42});
, for f(int)
, the implicit conversion sequence is the one to convert the element (i.e. 42
) to int
, which is an exact match; for f(std::vector<int>)
, user-defined conversion (converting std::initializer_list<int>
to std::vector<int>
) is required then it's a worse match.
PS: if the braced-initializer contains more than one element such as {42, 42}
, f(std::vector<int>)
will be selected.
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