1. ホーム
  2. c++

[解決済み] 移動したオブジェクトはどうすればいいですか?

2022-04-28 04:48:27

質問

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

例えば、関数テンプレート 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!
}

もちろん、moved-fromオブジェクトに代入することは可能でなければなりません。そうでなければ、2行目と3行目は失敗します。では、moved-fromオブジェクトで他に何ができるのでしょうか?規格のどこにその詳細があるのでしょうか?

(ちなみに、なぜ T c = std::move(a); ではなく T c(std::move(a)); を1行目に入れるか)

どのように解決するのですか?

移動したオブジェクトは、不特定だが有効な状態で存在する。このことは、そのオブジェクトがもうあまり多くのことをできないかもしれない一方で、そのすべてのメンバー関数がまだ定義された振る舞いを示すべきであることを示唆しています。 operator= - そして、そのすべてのメンバーが定義された状態にあり、なおかつ破壊を必要とする。UDTごとに異なるため、Standardでは具体的な定義はありませんが、Standardの型の仕様を見つけることができるかもしれません。コンテナのようなものは比較的明白で、中身を移動させるだけであり、空のコンテナは明確に定義された有効な状態である。プリミティブは移動元のオブジェクトを変更することはない。

余談:確か T c = std::move(a) で、移動コンストラクタ (移動がない場合はコピーコンストラクタ) が明示的であれば、この関数は失敗します。