2016-10-26 4 views
1

aのコピーコンストラクタを呼び出しているのはなぜですか?std :: vectorの要素の移動が予想されましたが、代わりにパラメータとして渡そうとしたときにコピーが発生しました

class a { 
public: 
    a(int x) : x_(x) { std::cout << "a constructor" << std::endl; } 
    a(a&& a_) { std::cout << "a move constructor" << std::endl; } 
    a(const a& a_) { std::cout << "a copy constructor" << std::endl; } 

private: 
    int x_; 
}; 

class b { 
public: 
    b(std::vector<a>&& v) : v_(std::move(v)) {} 

private: 
    std::vector<a> v_; 
}; 

int main() { 
    b s({2, 3, 4, 5, 6}); 
} 

出力は以下の通りです:

a constructor 
a constructor 
a constructor 
a constructor 
a constructor 
a copy constructor 
a copy constructor 
a copy constructor 
a copy constructor 
a copy constructor 

ベクトルが所定の位置に作成され、右辺値参照として渡され、その後に移動されているので、私は何のコピーを期待していませんでした。実際に何が起こっていますか?

答えて

3

std::initializer_list<T>は、const Tオブジェクトの配列のラッパーです。 (より正確には、std::initializer_list<T>::referenceconst T&である)。 constに注目してください。その要素はリテラルにすることができるので、それはそうでなければなりません。

これはstd::initializer_listを取っstd::vectorのコンストラクタはコピーベクターへのリストから要素に、それはそれらを移動することはできませんがあることを意味します。

+1

より正確には、コンストラクタが 'std :: initializer_list '(ここで 'T'はベクトルの値型です)をテンプレートとし、' std :: initializer_list ' 'X')。さもなければ、 'a 'はベクトルによって構築できます。 –

関連する問題