Zuordnung kopieren / verschieben in std :: vector :: erase () und std :: deque :: erase ()

135

Bei der Beantwortung einer weiteren Frage bin ich auf leicht unterschiedliche Formulierungen für std::vector::erase()und gestoßen std::deque::erase().

Dies ist, was C ++ 14 über std::deque::erase( [deque.modifiers]/4-6, Hervorhebung von mir) sagt :

Effekte: ...

Komplexität: Die Anzahl der Aufrufe des Destruktors entspricht der Anzahl der gelöschten Elemente, aber die Anzahl der Aufrufe des Zuweisungsoperators ist nicht größer als die Anzahl der Elemente vor den gelöschten Elementen und die Anzahl der Elemente nach dem gelöschte Elemente.

Auslöser: Nichts, es sei denn, der Kopierkonstruktor, der Verschiebungskonstruktor, der Zuweisungsoperator oder der Verschiebungszuweisungsoperator von lösen eine Ausnahme aus T.

Und hier ist, was es über std::vector::erase( [vector.modifiers]/3-5) sagt :

Effekte: ...

Komplexität: Der Destruktor von Twird als die Anzahl bezeichnet, die der Anzahl der gelöschten Elemente entspricht, aber der Verschiebungszuweisungsoperator von Twird als die Häufigkeit bezeichnet, die der Anzahl der Elemente im Vektor nach den gelöschten Elementen entspricht.

Auslöser: Nichts, es sei denn, der Kopierkonstruktor, der Verschiebungskonstruktor, der Zuweisungsoperator oder der Verschiebungszuweisungsoperator von lösen eine Ausnahme aus T.

Wie Sie sehen können, sind die Ausnahmespezifikationen für beide gleich, std::vectores wird jedoch ausdrücklich erwähnt, dass der Verschiebungszuweisungsoperator aufgerufen wird.

Es gibt auch Voraussetzung für Tsein MoveAssignablefür erase()die Arbeit mit beiden std::vectorund std::deque(Tabelle 100), aber dies bedeutet nicht , das Vorhandensein des Umzugs Zuweisungsoperator: eine Kopie Zuweisungsoperator definieren kann, und nicht bewegen Zuweisungsoperator definieren, und diese Klasse sein MoveAssignable.

Nur für den Fall, ich habe mich bei GCC und Clang erkundigt und std::vector::erase()rufe tatsächlich den Kopierzuweisungsoperator auf, wenn es keinen Verschiebungszuweisungsoperator gibt, und std::deque::erase()mache dasselbe ( DEMO ).

Die Frage ist also: Habe ich etwas verpasst oder ist dies ein (redaktionelles) Problem im Standard?

Update: Ich habe eine LWG-Ausgabe Nr. 2477 eingereicht .

Anton Savin
quelle
14
Scheint ein Defekt in der Norm zu sein.
Barry
4
^ ack. Ein LWG-Thema wäre angebracht.
Columbo
4
Normalerweise ist der Standardentwurf gut genug. Dies ist einer der Fälle, in denen Sie sich die Realität ansehen sollten.
Mark Ransom
3
@MarkRansom Die aktuelle Quelle des Standards für std :: deque und std :: vector ist dieselbe wie in der Frage, sodass die Wahrscheinlichkeit, dass sich die endgültige Version unterscheidet, sehr gering ist.
Anton Savin
3
N4141 hat den gleichen Wortlaut wie N4140.
Brian

Antworten:

9

Bei der Lenexa-Sitzung erhielt das Problem mit der vorgeschlagenen Lösung den Status "Sofort" :

Dieser Wortlaut bezieht sich auf N4296.

Ändern Sie 23.3.3.4 [deque.modifiers] / 5 in:

-5- Komplexität : Die Anzahl der Aufrufe des Destruktors von entsprichtT der Anzahl der gelöschten Elemente, aber die Anzahl der Aufrufe des Zuweisungsoperators vonT ist nicht größer als die Anzahl der Elemente vor den gelöschten Elementen und dem Anzahl der Elemente nach den gelöschten Elementen.

Ändern Sie 23.3.6.5 [vector.modifiers] / 4 in:

-4- Komplexität : Der Destruktor von Twird als die Anzahl bezeichnet, die der Anzahl der gelöschten Elemente entspricht, aber der Verschiebungszuweisungsoperator von Twird als die Anzahl der Male bezeichnet, die der Anzahl der Elemente im Vektor nach den gelöschten Elementen entsprechen.

Das heißt, wenn der Beschluss angenommen wird, wird die Verschiebungszuweisung für nicht besonders erwähnt std::vector::erase, und auch der Wortlaut für std::deque::erasewird ein wenig geklärt.

Anton Savin
quelle