2011-01-29 7 views
11

は、次のことを考えてみましょう:異なるクラスから移動コンストラクタを定義する必要はありますか?

struct X 
{ 
    Y y_; 

    X(const Y & y) :y_(y) {}  
    X(Y && y) :y_(std::move(y)) {} 
}; 

は、移動セマンティクスを最大限に活用するために、第2の1のようなコンストラクタを定義することが必要ですか?あるいは、適切な状況で自動的に世話をするでしょうか?

+0

移動コンストラクタまたは代入演算子は、[特定の状況では]暗黙的に生成されます(http://stackoverflow.com/questions/4819936/why-no-default-move-assignment-move-constructor/4820339#4820339)。ここでコピーコンストラクタを宣言しているので、適切な移動コンストラクタを宣言して定義する必要があります。ただし、これらの両方を削除して、特定のケースで同じ動作をすることができます。 –

+1

@James:便利な情報です。しかし、ここではコピーコンストラクタを定義しませんでした。私はYからXまでのコンストラクタを定義しました。 –

+0

ああ。申し訳ありません、私は手紙を見て、彼らはすべて同じだったと思った。 –

答えて

7

はい、いいえ。

struct X 
{ 
    Y y_; 

    X(Y y) : // either copy, move, or elide a Y 
    y_(std::move(y)) // and move it to the member 
    {} 
}; 

あなたがこれまで*「私は、このデータの私自身のコピーが必要」なデザインで言うならば、あなただけの値で引数を取り、それがために必要がある場合にそれを移動する必要があります:あなたのコードはこれだけでなければなりません。その値を構築する方法を決定するのはあなたの仕事ではありません。それはその値の利用可能なコンストラクターに任されているので、その選択肢を何でも作り、最終結果で作業させましょう。

*これは、例えば、当然のことながら、あまりにも機能に適用されます。あまりにもC++ 03に適用される

void add_to_map(std::string x, int y) // either copy, move or elide a std::string 
{ 
    // and move it to where it needs to be 
    someMap.insert(std::make_pair(std::move(x), y)); 
} 

注意、多少、タイプはデフォルト構築可能とスワップ可能だった場合(これはすべてが動いている):

// C++03 
struct X 
{ 
    std::string y_; 

    X(std::string y) // either copy or elide a std::string 
    { 
     swap(y_, y); // and "move" it to the member 
    } 
}; 

これは広く行われていないようですが、

+0

まさに私が探していたものです。それらを1つの機能で実行する方法です。ありがとうGMAN。 –

1

はい、必要です。 const refはコピーであって、移動ではありません。

関連する問題