web-dev-qa-db-ja.com

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

別の質問 に答える過程で、私はstd::vector::erase()std::deque::erase()のわずかに異なる表現につまずいた。

これは、C++ 14が_std::deque::erase_(_[deque.modifiers]/4-6_、エンファシスマイン)について言っていることです:

効果:...

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

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

そして、これは_std::vector::erase_(_[vector.modifiers]/3-5_)について言うことです:

効果:...

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

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

ご覧のとおり、両方の例外の仕様は同じですが、_std::vector_の場合、移動代入演算子が呼び出されることが明示的に述べられています。

_std::vector_と_std::deque_(表100)の両方で動作するためのerase()TにはMoveAssignableであるという要件もありますが、 tは、移動代入演算子の存在を意味します。コピー代入演算子を定義できますが、移動代入演算子は定義できません。このクラスはMoveAssignableになります。

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

質問は次のとおりです。何かを見逃したのですか、それとも標準の(編集上の)問題ですか?

Update:LWG issue#2477 を提出しました。

135
Anton Savin

レネクサ会議で問題を解決する 即時ステータスを取得 提案された解決策:

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

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

-5- Complexity:デストラクタの呼び出し回数of Tは消去された要素の数と同じです。ただし、代入演算子of Tの呼び出し数は、消去された要素の前の要素数と要素数の小さい方以下です。消去された要素の後。

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

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

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

9
Anton Savin