151

標準は、オブジェクトが移動された後、オブジェクトで何ができるかを正確に定義していますか?以前は、移動元のオブジェクトでできることは、オブジェクトを破棄することだけだと思っていましたが、それだけでは不十分です。

たとえばswap、標準ライブラリで定義されている関数テンプレートを考えてみましょう。

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

明らかに、移動元のオブジェクトに割り当てることができる必要があります。そうしないと、2行目と3行目が失敗します。では、moved-fromオブジェクトで他に何ができるでしょうか?これらの詳細は、標準のどこに正確に記載されていますか?

(ちなみに、 1行T c = std::move(a);目ではなくなぜT c(std::move(a));ですか?)

4

2 に答える 2

127

17.6.5.15 [lib.types.movedfrom]

C ++標準ライブラリで定義されている型のオブジェクトは、(12.8)から移動できます。移動操作は、明示的に指定することも、暗黙的に生成することもできます。特に明記されていない限り、そのような移動元のオブジェクトは、有効であるが指定されていない状態に置かれるものとします。

オブジェクトが不特定の状態にある場合、前提条件のないオブジェクトに対して任意の操作を実行できます。実行したい前提条件のある操作がある場合、オブジェクトの不特定状態が前提条件を満たしているかどうかわからないため、その操作を直接実行することはできません。

一般に前提条件がない操作の例:

  • 破壊
  • 割り当て
  • 、、などのconstgetオブザーバーemptysize

一般的に前提条件がある操作の例:

  • 間接参照
  • pop_back

この回答は、ここにビデオ形式で表示されます:http ://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s

于 2011-08-11T15:09:57.783 に答える
60

移動元オブジェクトは、指定されていないが有効な状態で存在します。これは、オブジェクトがもう多くのことを実行できない可能性がある一方で、そのすべてのメンバー関数は、定義された動作を示すoperator=必要があり、定義された状態のすべてのメンバーを含む必要があり、それでも破棄が必要であることを示しています。標準は各UDTに固有であるため、特定の定義はありませんが、標準タイプの仕様を見つけることができる場合があります。コンテナのようなものは比較的明白です。それらはコンテンツを移動するだけで、空のコンテナは明確に定義された有効な状態です。プリミティブは、移動元のオブジェクトを変更しません。

補足:T c = std::move(a)移動コンストラクター(または移動が提供されていない場合はコピーコンストラクター)が明示的である場合、関数は失敗するためだと思います。

于 2011-08-11T14:30:45.773 に答える