Forcing std::vector overload instead of int overload on list with one element

后端 未结 2 1475
[愿得一人]
[愿得一人] 2021-01-19 09:28

Consider the code below:

#include 
#include 

void f(std::vector v) {std::cout << __PRETTY_FUNCTION__ <<         


        
相关标签:
2条回答
  • 2021-01-19 09:41

    Forcing std::vector overload

    int main()
    {
        f(std::vector<int>{42}); // the vector overload is being picked up now
    }
    

    Why isn't the vector(initializer_list) constructor being picked up?

    Assume that another header declares a void f(std::set<int> v).

    How would you like the compiler to react when faced with f({1}): construct a vector or construct a set?

    0 讨论(0)
  • 2021-01-19 09:59

    Braced initializer has no type, we can't say {42} is an int or std::initializer_list<int>. When it's used as an argument, special rules for overload resolution will be applied for overloaded function call.

    (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

    {42} has only one element with type int, then it's exact match for the overload void f(int). While for void f(std::vector<int>) a user-defined conversion is needed. So void f(int) will be picked up here.

    Is there any way of forcing the compiler to pick the std::vector overload (without explicitly constructing std::vector<int>{42}) even on 1-element lists?

    As a wordaround, you can put additional braces to force the compiler construct a std::initializer_list<int> and then pick up void f(std::vector<int>):

    f({{42}});
    

    LIVE

    0 讨论(0)
提交回复
热议问题