2011-07-20 29 views
22

explicitキーワードはは、コピーコンストラクタを除いて、一つの引数で呼び出すことができます すべて 最もコンストラクタのために推奨されます。明示的な移動コンストラクタ?

コピーコンストラクタの場合は、(関数呼び出し、リターンなどを介した暗黙のコピーを禁止するために)使用しますが、通常は必要ではありません。

コンストラクタの移動について?明示的に使用する合理的なユースケースはありますか?ここでは良い練習は何ですか?

+0

"コピーコンストラクタ"と "1つの引数で呼び出すことができるコンストラクタ"の違いは何ですか?私はちょうどDeadMGsとの混乱がありました。私はこれらが同じものだと思ったからです。これは、それが使用されている方法であり、(「明示的」以外の)コンストラクタの宣言方法ではありません。それとも私は狂った? – Steve314

+3

@ Steve314:単一引数コピーコンストラクタは、具体的にはコンストラクタT([const] [volatile] T&) 'です。 12.8/2。 'T(int)'は1つの引数で呼び出すことができるコンストラクタですが、 'T 'のインスタンスを「コピー」しないため、コピーコンストラクタではありません。 –

+0

@ Steve Jessop - はい、もちろんです。明らかに私は脳死してしまった。 – Steve314

答えて

19

explicit移動コンストラクタは、標準アルゴリズム。たとえば、std::swap<T>にはMoveConstructibleがTであることが必要です。次に、MoveConstructibleは式で指定されます。T u = rv;rvTの右辺です)。

指定された型の非明示的コピーコンストラクタも非明示的移動コンストラクタもない場合、T u = rv;は無効であり、その型はstd::swapで使用できません。 (しかし、この特定の例では、例えばT u(rv);を使用することによって、所望の機能を提供するようにstd::swapを特化することが可能である。

より簡単に言えば、explicit移動またはコピーコンストラクタは期待に反し、ジェネリックコードでも使用できません。

MoveConstructible要件を置く標準ライブラリのいくつかの他の部分:

  • 例えばで使用unique_ptr<T, D>
  • コールラッパーの削除手段、 bind(渡されたすべての減衰したタイプが懸念している)
  • threadasynccall_once(すべてのコールのラッパーの面で指定)
  • sortstable_sortnth_elementsort_heap
5

おそらく、ほとんどの用途で暗黙的な移動コンストラクタが必要です。一般に、コピーコンストラクタと同じカテゴリに分類されます。 すべてについては明示的ではありませんが、ほとんどの場合は推奨されます。移動コンストラクタはそのリストにありません。

5

explicitキーワードが推奨されます予期しない場所での驚くべき変換を避けるために、を変換する(単一引数)のためにコンストラクタを使用します。

コピーコンストラクタとムーブコンストラクタは、その意味で「驚く」ことはほとんどありません。大部分は予想通りに起こります。あなたがそれらを必要としないなら、私は彼らに明示されているよりむしろ=deleteとマークされると期待します。

2

実際の質問は、どのように明示的なムーブコンストラクタを使用できるかということですか?それはrvaluesで呼び出すことはできないので、コンパイラは常にコピーコンストラクタを選択しなければなりません。

編集:http://www.ideone.com/nm7KM

+0

[直接初期化を使用する](http://www.ideone.com/W2BT3)。 –

+0

@Luc:いいですね!おそらく明示的な移動コンストラクタを呼び出すことができる唯一の方法です。 –

+0

+1良い質問のために、Gene :)答えのためのLucのためのより多くの小道具(それは将来の参考のためにあなたのポストにそれを追加すると便利かもしれません)。ありがとう! – Kos

0

関数から値で返す、暗黙のムーブコンストラクタは通常、プロセスをより効率的に行うことができます:ここでの例へのリンクがあります。

+0

少し話題ですが、良い点ですが、実際には、可能であれば、インラインで移動コンストラクタを作成する理由があると思います。 – Kos

関連する問題