2017-04-04 7 views
1

例Aで使用されている移動セマンティクスは必須であり、どの構造が優れていますか?私はいつもコンストラクタでstd :: moveを使うべきですか?

例A:

struct A 
{ 
    std::string a; 
    A(std::string a) : a(std::move(a)){ } 
}; 

例B:

struct B 
{ 
    std::string b; 
    B(const std::string& b) : b(b){ } 
}; 

私はこれが重複質問であるとは考えていません。私は具体的にどのクラスのコンストラクタでメンバ初期化を使用する観点から優れているかを尋ねています。他の質問に記載されている例や回答のいずれも、会員の初期化については触れられていません。

コンストラクタが参照パラメータで呼び出され、そのメンバにコピーされているのが好きではありません。複数のコピー操作を行うのは無駄かもしれないようです。

データをできるだけ効率的にメンバーにパイプしたいが、コンストラクタのパラメータとしてrvaluesを使用したくない。

+3

値が 'int'または他の単一値のプリミティブである場合、' move'または参照(constなど)を使用すると無意味です。また、明示的なコンストラクタのない構造体がこの場合に優れていると考えています。 – ShadowRanger

+0

例を簡略化するために 'int'を使用しました。それが 'std :: string'や他のもっと複雑なクラスだったら、どちらが優れていますか? (私の答えを編集し、 'int'を' std :: string'に変更しました) –

+0

[std :: move()とは何か、そしていつ使うべきでしょうか?](http://stackoverflow.com/questions)/3413470/what-is-stdmove-when-be-be-be-used-use) – chbchb55

答えて

0

私の意見では、両方を比較するのは本物ではありません。

倍の大半は、実装コピーコンストラクタは深いコピーを作成し、背後にある主な目的は、ソースオブジェクトが変更されないであることを確認することです。

std :: moveは最終的にrvalue参照用のコンストラクタを呼び出すだけでポインタをコピーし、ソースオブジェクトポインタをNULLに設定できます。このシナリオは、主に一時オブジェクトです。

だから、両方の例は、2つの異なる目的のために意図されている、(コピーコンストラクタ)を使用すると、ソースオブジェクトがそのままになりたい、と(STD ::動きは)一時オブジェクトを扱うためのものです。

+1

しかし、パラメータは 'std :: move'の場合に値渡しされるので、' std :: string'のコピーコンストラクタを使って一時的なオブジェクトを作成し、それをメンバ変数に移動します。私が言うことができるように、2つのケースは同等であり、どちらを選択するかは単なるスタイルの問題です。 –

+0

例はありませんコピーを作成するために仲介者として参照を使用していないため、やや優れていますか? –

+0

例Aにもコピーコンストラクタが実装されていますか?あなたが値渡し時にデフォルトのコピーコンストラクタが呼び出されない場合でも。したがって、例Aでは、 "完全なコピーコンストラクタの呼び出し+ std :: move"のようにはなりませんか? – Naidu

関連する問題