【问题标题】:Single-Element-Vector Initialization in a Function Call函数调用中的单元素向量初始化
【发布时间】:2018-03-15 20:45:49
【问题描述】:

考虑以下示例代码:

示例:

void print(int n) {
    cout << "element print\n";
}

void print(vector<int> vec) {
    cout << "vector print\n";
}

int main() {
   /* call 1 */ print(2);
   /* call 2 */ print({2});
   std::vector<int> v = {2};
   /* call 3 */ print(v);
   /* call 4 */ print( std::vector<int>{2} );
   return 0;
}

生成以下输出:

element print
element print
vector print
vector print

为什么对 print 函数的调用(上例中的调用 2)与接受单个值的函数相匹配?我在这个调用中创建了一个向量(包含一个元素),所以它不应该匹配以向量作为输入调用print吗?

这部分讨论了in an other question,其中提供的解决方案适用于具有超过 1 个元素的向量。

【问题讨论】:

    标签: c++ c++11 vector stl overload-resolution


    【解决方案1】:

    因为第一个重载在 print({2}); 的重载决议中获胜。

    在这两种情况下copy list initialization 都适用,对于第一个过载采用int

    (强调我的)

    否则(如果T 不是类类型),如果花括号初始化列表只有一个元素并且T 不是引用类型或者是引用类型与元素的类型兼容,T 是直接初始化(在直接列表初始化中)或复制初始化(在复制列表初始化中),但不允许缩小转换。

    {2}只有一个元素,可以直接初始化一个int作为参数;这是完全匹配的。

    对于第二次重载以std::vector&lt;int&gt;

    否则,T 的构造函数将分两个阶段考虑:

    • 检查所有将std::initializer_list 作为唯一参数或作为第一个参数(如果其余参数具有默认值)的构造函数,并通过重载决议与std::initializer_list 类型的单个参数进行匹配

    这意味着std::initializer_list&lt;int&gt; 被构造并用作std::vector&lt;int&gt; 的构造函数参数(以构造print 的参数)。需要一次用户定义的转换(通过std::vector 的构造函数获取一个std::initializer_list),那么它比第一次重载更差。

    【讨论】:

      【解决方案2】:

      {2} 是许多类型的合法初始化器,包括int。重载解析更喜欢与需要进一步构造的类型完全匹配的类型。

      【讨论】:

        【解决方案3】:

        不,这不是你所做的,你正在创建一个 initializer_list。

        见:http://en.cppreference.com/w/cpp/utility/initializer_list

        调用 1) 调用单个元素

        调用 2) initializer_list 创建单个 int 元素

        调用 3) 给定一个 Vector 对象

        调用 4) 给定一个 Vector 对象

        重载结果更喜欢在std::vector参数方法之前使用int参数方法,因为类型转换较少。 int 参数直接匹配,vector 参数需要额外转换。

        例如:

        void print(std::initializer_list<int> list){
            cout << "initializer_list print\n";
        }
        

        调用 2 会导致输出为“initializer_list print”

        【讨论】:

        • 重要提示:花括号初始化列表是type-less,而不是std::initializer_list。所以你的第一句话是错误的。
        猜你喜欢
        • 1970-01-01
        • 2012-12-08
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2013-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多