std :: vector :: erase()およびstd :: deque :: erase()での割り当てのコピー/移動


135

答えるの過程では別の質問を私が少し異なる文言につまずいたstd::vector::erase()std::deque::erase()

これはC ++ 14が言っていることですstd::deque::erase[deque.modifiers]/4-6私の強調):

効果: ...

複雑さ:デストラクタへの呼び出しの数は消去された要素の数と同じですが、代入演算子の呼び出しの数の数は、消去された要素の前の要素の数と後の要素の数の小さい方以下です消去された要素。

スローコピーコンストラクター、移動コンストラクター、割り当て演算子、または移動割り当て演算子によって例外がスローされない限り、何も発生しません。T

そして、これがstd::vector::erase[vector.modifiers]/3-5)について言っていることです:

効果: ...

複雑さ:のデストラクタはT、消去された要素の数と等しい回数と呼ばれますが、移動代入演算子T、消去された要素の後のベクトル内の要素の数と等しい回数と呼ばれます。

スロー:のコピーコンストラクター、移動コンストラクター、割り当て演算子、または移動割り当て演算子によって例外がスローされない限り、何も起こりませんT

ご覧のとおり、両方の例外仕様は同じですが、std::vector代入代入演算子が呼び出されることが明示されているためです。

以下のための要件もありますTされるようにMoveAssignableするためにerase()、両方との仕事にstd::vectorとはstd::deque(表100)が、これは移動代入演算子の存在を意味するものではありません。一つはコピー代入演算子を定義し、移動代入演算子を定義することはできませんが、このクラスの意志をであるMoveAssignable

念のため、GCCとClangで確認しました。実際にstd::vector::erase()移動代入演算子がない場合は、コピー代入演算子を呼び出しstd::deque::erase()、同じことを行います(デモ)。

だから問題は、私は何かを逃したのか、またはこれは規格の(編集上の)問題なのか?

更新:LWGの問題#2477を 送信しました。


14
標準の欠陥のようです。
バリー

4
^確認。LWGの問題が適切でしょう。
コロンボ2015

4
通常、ドラフト標準で十分です。これは、本物を見なければならないケースの1つです。
Mark Ransom

3
@MarkRansom std :: dequeおよびstd :: vectorの標準の現在のソースは質問と同じであるため、最終バージョンが異なる可能性はほとんどありません。
Anton Savin

3
N4141の表現はN4140と同じです。
ブライアン

回答:


9

レネクサ会議で、この問題提案された解決策で即時ステータスになりました:

この表現はN4296に関連しています。

23.3.3.4 [deque.modifiers] / 5を次のように変更します。

-5- 複雑:デストラクタの呼び出しの数のがT消去された要素の数が、代入演算子へのコール数と同じであるT消去された要素および前それ以上の要素数の少ないより消去された要素の後の要素の数。

23.3.6.5 [vector.modifiers] / 4を次のように変更します。

-4- 複雑さ:のデストラクタはT、消去された要素の数と等しい回数と呼ばれますが、移動代入演算子はT、消去された要素の後のベクトル内の要素の数と等しい回数と呼ばれます。

つまり、解決が受け入れられた場合、の移動割り当てについての特別な言及はなくstd::vector::erase、の表現もstd::deque::erase少し明確になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.