50

C ++ 11標準は、標準ライブラリに関連する自己移動代入について何と言っていますか?より具体的には、何が保証されているのselfAssignでしょうか。

template<class T>
std::vector<T> selfAssign(std::vector<T> v) {
  v = std::move(v);
  return v;
}
4

2 に答える 2

40

17.6.4.9関数の引数[res.on.arguments]

1以下のそれぞれは、特に明記されていない限り、C++標準ライブラリで定義されている関数のすべての引数に適用されます。

..。

  • 関数の引数が右辺値参照パラメーターにバインドする場合、実装は、このパラメーターがこの引数への一意の参照であると想定する場合があります。[注:パラメーターがT &&形式のジェネリックパラメーターであり、タイプAの左辺値がバインドされている場合、引数は左辺値参照(14.8.2.1)にバインドされるため、前の文ではカバーされません。— end note] [注:プログラムが左辺値をライブラリ関数に渡すときに左辺値をx値にキャストする場合(たとえば、引数move(x)を使用して関数を呼び出すことにより)、プログラムはその関数にその左辺値を処理するように効果的に要求します。一時的なものとして。実装は、引数がanlvalueの場合に必要になる可能性のあるエイリアシングチェックを自由に最適化できます。—文末脚注]

したがって、の実装でstd::vector<T, A>::operator=(vector&& other)は、それが優先値であると想定できotherます。また、otherが優先値の場合、自己移動代入はできません。

起こりそうなこと:

vリソースのない状態(容量0)のままになります。すでに容量が0の場合v、これはノーオペレーションになります。

アップデート

最新の作業ドラフトであるN4618MoveAssignableは、要件で次の表現を明確に示すように変更されました。

t = rv

rvは右辺値です)、同じオブジェクトを参照していない場合は、割り当て前tの同等の値である必要があります。とにかく、割り当て後の状態は指定されていません。さらに明確にするための追加の注記があります:rvtrvrv

rv同じオブジェクトtを参照しているかどうかに関係なく、それを使用しているライブラリコンポーネントの要件を満たしている必要があります。rv

于 2012-10-29T18:55:59.147 に答える
0

複数のリンクを持つEricNieblerによる関連する投稿があります。たとえば、HowardHinnantによるこの回答への投稿です。

最新のС++20ワーキングドラフト(N4861)は、私の好みではまだあいまいです。ただし、最近のLibrary Working Groupの問題2839があり、次の明示的なステートメントが追加されています[lib.types.movedfrom]/2

C ++標準ライブラリで定義されているタイプのオブジェクトは、それ自体に移動割り当て(11.4.6 [class.copy.assign])できます。このような割り当てにより、特に指定されていない限り、オブジェクトは有効ですが指定されていない状態になります。

それはすでにC++23のN4885ワーキングドラフトに含まれていました。

したがって、selfAssign未定義の動作を引き起こさないことが保証されており、の追加の保証がないため、有効な状態std::vectorのままにしておきます。v

于 2021-04-05T11:50:38.560 に答える