web-dev-qa-db-ja.com

移動元オブジェクトで何ができますか?

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

たとえば、標準ライブラリで定義されている関数テンプレート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行目が失敗します。では、移動元オブジェクトで他に何ができますか?標準のどこでこれらの詳細を正確に見つけることができますか?

(ところで、なぜ1行目のT c = std::move(a);ではなくT c(std::move(a));なのですか?)

132
fredoverflow

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

サイドノート:T c = std::move(a)であると思うので、移動コンストラクター(または移動が提供されない場合はコピーコンストラクター)が明示的である場合、関数は失敗します。

52
Puppy