Copier / déplacer l'affectation dans std :: vector :: erase () et std :: deque :: erase ()

135

En répondant à une autre question, je suis tombé sur des formulations légèrement différentes pour std::vector::erase()et std::deque::erase().

Voici ce que dit C ++ 14 std::deque::erase( [deque.modifiers]/4-6, c'est moi qui souligne):

Effets: ...

Complexité: Le nombre d'appels au destructeur est le même que le nombre d'éléments effacés, mais le nombre d'appels à l' opérateur d'affectation n'est pas supérieur au moindre du nombre d'éléments Avant les éléments effacés et du nombre d'éléments après le éléments effacés.

Génère: rien sauf si une exception est levée par le constructeur de copie, le constructeur de déplacement, l'opérateur d'affectation ou l'opérateur d'affectation de déplacement de T.

Et voici ce qu'il dit à propos de std::vector::erase( [vector.modifiers]/3-5):

Effets: ...

Complexité: Le destructeur de Test appelé le nombre de fois égal au nombre d'éléments effacés, mais l' opérateur d'affectation de déplacement de Test appelé le nombre de fois égal au nombre d'éléments dans le vecteur après les éléments effacés.

Génère: rien sauf si une exception est levée par le constructeur de copie, le constructeur de déplacement, l'opérateur d'affectation ou l'opérateur d'affectation de déplacement de T.

Comme vous pouvez le voir, les spécifications d'exception pour les deux sont les mêmes, mais std::vectoril est explicitement mentionné que l'opérateur d'assignation de déplacement est appelé.

Il est également nécessaire Td'être MoveAssignablepour erase()travailler avec les deux std::vectoret std::deque(Tableau 100), mais cela n'implique pas la présence de l'opérateur d'affectation de déplacement: on peut définir un opérateur d'affectation de copie, et non pas définir l'opérateur d'affectation de déplacement, et cette classe sera être MoveAssignable.

Juste au cas où, j'ai vérifié avec GCC et Clang, et j'appelle effectivement l' std::vector::erase()opérateur d'affectation de copie s'il n'y a pas d'opérateur d'affectation de déplacement, et std::deque::erase()fait de même ( DEMO ).

La question est donc: ai-je manqué quelque chose ou est-ce un problème (éditorial) dans la norme?

Mise à jour: j'ai soumis un problème LWG # 2477 .

Anton Savin
la source
14
Cela semble être un défaut de la norme.
Barry le
4
^ ack. Un problème LWG serait approprié.
Columbo
4
En général, le projet de norme est assez bon. C'est l'un de ces cas où vous devriez regarder la vraie chose.
Mark Ransom
3
@MarkRansom la source actuelle du standard pour std :: deque et std :: vector est la même que dans la question, donc la probabilité que la version finale diffère est très faible.
Anton Savin
3
N4141 a le même libellé que N4140.
Brian

Réponses:

9

Lors de la réunion de Lenexa, le problème a obtenu le statut immédiat avec la résolution proposée:

Ce libellé est relatif à N4296.

Remplacez 23.3.3.4 [deque.modifiers] / 5 par:

-5- Complexité : Le nombre d'appels au destructeur deT est le même que le nombre d'éléments effacés, mais le nombre d'appels à l'opérateur d'affectation deT n'est pas supérieur au moindre du nombre d'éléments avant les éléments effacés et le nombre d'éléments après les éléments effacés.

Remplacez 23.3.6.5 [vector.modifiers] / 4 par:

-4- Complexité : Le destructeur de Test appelé le nombre de fois égal au nombre d'éléments effacés, mais l' opérateur d'affectation de déplacement de Test appelé le nombre de fois égal au nombre d'éléments dans le vecteur après les éléments effacés.

Autrement dit, si la résolution est acceptée, il n'y aura pas de mention spéciale de l'affectation de déplacement pour std::vector::erase, et le libellé de std::deque::erasesera également clarifié un peu.

Anton Savin
la source