92

移動したコンテナを再利用する正しい方法は何ですか?

std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);

// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize

container.push_back(2);
assert(container.size() == 1 && container.front() == 2);

私がC++0x標準ドラフトで読んだものから; 移動後のオブジェクトは

「特に明記されていない限り、そのような移動元のオブジェクトは、有効であるが指定されていない状態に置かれるものとします。」

「他の方法で指定された」インスタンスは見つかりませんでした。

ver3は少し回り道で、ver1の方がはるかに好ましいと思いますが、vec3は追加の最適化を可能にしますが、一方で、簡単に間違いを引き起こす可能性があります。

私の仮定は正しいですか?

4

3 に答える 3

109

仕様「有効だが指定されていない状態」のセクション17.3.26から:

オブジェクトの不変条件が満たされ、オブジェクトに対する操作がそのタイプに対して指定されたとおりに動作することを除いて、指定されていないオブジェクトの状態[例:タイプのオブジェクトxstd::vector<int>有効であるが指定されていない状態にある場合、x.empty()無条件に呼び出すx.front()ことができ、呼び出すことができますx.empty()falseを返す場合のみ。—例を終了]

したがって、オブジェクトはライブです。前提条件を必要としない操作を実行できます(最初に前提条件を確認しない限り)。

clearたとえば、前提条件はありません。そして、オブジェクトを既知の状態に戻します。したがって、それをクリアして、通常どおりに使用します。

于 2012-02-06T23:29:48.267 に答える
16

オブジェクトが有効であるが未定義の状態にあるということは、基本的に、オブジェクトの正確な状態は保証されませんが、それは有効であり、そのようなメンバー関数(または非メンバー関数)は、依存しない限り機能することが保証されることを意味します特定の状態を持つオブジェクトに対して。

メンバー関数には、オブジェクトの状態に関する前提条件がないため(clear()もちろん、それが有効であることを除いて)、移動元のオブジェクトで呼び出すことができます。一方、たとえばfront()、コンテナが空でないことに依存しているため、空でないことが保証されていないため、呼び出すことはできません。

したがって、ver2とver3の両方で問題ないはずです。

于 2012-02-06T23:30:44.953 に答える
-9

移動元のオブジェクトでは何もできないと思います(破棄する場合を除く)。

swap代わりに、移動のすべての利点を取得しながら、コンテナを既知の状態のままにするために使用することはできませんか?

于 2012-02-06T23:26:40.207 に答える