【问题标题】:what is the return type of list initialisation?列表初始化的返回类型是什么?
【发布时间】:2018-03-02 16:11:54
【问题描述】:

有没有人想解释一下为什么案例 1 和案例 2 对这段代码 sn-p 有不同的输出。

struct A {
    A() { cout << "A()" << endl; }
    A(int i) { cout << "A(int)" << endl; }
    A(const A&) { cout << "A(const A&)" << endl; }
    A(A&&) noexcept { cout << "A(A&&)" << endl; }
    A& operator=(const A&) { cout << "operator=(const A&)" << endl; return *this; }
    A& operator=(A&&) noexcept { cout << "operator=(A&&)" << endl; return *this; }
    friend bool operator< (const A&, const A&) { return true; }
};

int main() {
    std::set<A> aSet;
    aSet.insert(1);       // case 1
    //aSet.insert({1});   // case 2

    return 0;
}

对于情况 1,输出为:

A(int)
A(A&&)

对于情况 2 是:

A(int)
A(const A&)

编译器版本为:

g++ --version g++-7 (SUSE Linux) 7.2.1 20170901 [gcc-7-branch 修订版 251580] 版权所有 (C) 2017 Free Software Foundation, Inc.

【问题讨论】:

    标签: c++ c++11 list-initialization


    【解决方案1】:

    std::set::insert 的相关重载为:

    std::pair<iterator,bool> insert( value_type const& value ); // #1
    std::pair<iterator,bool> insert( value_type&& value );      // #2
    void insert( std::initializer_list<value_type> ilist );     // #6
    

    当您调用aSet.insert(1); 时,它会优先调用#2 而不是#1 - 这将通过A(int ) 创建一个新的A,然后将其移动到集合中。因此,A(A&amp;&amp; )

    但是,当您调用aSet.insert({1}) 时,选择的重载是#6。每当您使用列表初始化时,std::initializer_list 候选者是强烈首选(基本上,我们首先考虑这些候选者进行重载解析,然后,如果我们不这样做找到一个,考虑其余部分,我们是否重做重载解决方案)。由于std::initializer_listconst array 支持,一旦我们通过A(int ) 创建了A,我们必须 将其复制出来——我们不能移动它。因此A(A const&amp; )

    【讨论】:

    • 这意味着对于列表初始化构造函数,出于兼容的原因,我们得到一个“const”对象。由于对象有一个顶级常量,插入操作必须采用复制构造函数而不是移动构造函数。我说的对吗?
    • @fetag 没有“列表初始化构造函数”,也不知道你说的“兼容原因”是什么意思。
    • 基于您所说:“由于 std::initializer_list 由 const 数组支持”,我认为该语句 aSet.insert({1}) 可以类比如下: const A temp = A {1}; aSet.insert(temp);
    • @fetag: "我认为这个语句 aSet.insert({1}) 可以类推如下: const A temp = A{1}; aSet.insert(temp);" 记住:使用列表初始化时,initializer_lists 总是获胜。因此,如果完全有可能调用带有initializer_list 的东西,那么列表初始化就会这样做。这就是为什么您必须小心使用它的时间和地点。
    • @fetag 因为std::initializer_list&lt;T&gt;T const 数组周围的代理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多