列表初始化的返回类型是什么?

时间:2017-09-21 10:36:54

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

有没有人想解释为什么案例1和案例2对此代码段有不同的输出。

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 revision 251580]   版权所有(C)2017 Free Software Foundation,Inc。

1 个答案:

答案 0 :(得分:4)

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

当您调用优先于#1调用#2的aSet.insert(1);时,将通过A创建新的A(int ),然后将其移至集合中。因此,A(A&& )

但是,当您致电aSet.insert({1})时,所选的过载为#6。每当你使用列表初始化时,std::initializer_list候选人强烈偏好(基本上,我们首先考虑那些候选人而首先重载决议 然后,只有当我们不做找不到一个,我们考虑其余的重做重载决策。由于std::initializer_listconst array支持,一旦我们通过A创建A(int ),我们必须将其复制出来 - 我们无法移动它。因此A(A const& )