Copiar / mover asignación en std :: vector :: erase () y std :: deque :: erase ()

135

En el proceso de responder otra pregunta, me topé con palabras ligeramente diferentes para std::vector::erase()y std::deque::erase().

Esto es lo que dice C ++ 14 sobre std::deque::erase(el [deque.modifiers]/4-6énfasis es mío):

Efectos: ...

Complejidad: el número de llamadas al destructor es el mismo que el número de elementos borrados, pero el número de llamadas al operador de asignación no es mayor que el menor número de elementos antes de los elementos borrados y el número de elementos después del elementos borrados

Lanzamientos: nada a menos que el constructor de copias, el constructor de movimientos, el operador de asignación o el operador de asignación de movimientos arrojen una excepción T.

Y aquí está lo que dice sobre std::vector::erase( [vector.modifiers]/3-5):

Efectos: ...

Complejidad: El destructor de Tse llama el número de veces igual al número de elementos borrados, pero el operador de asignación de movimiento de Tse llama el número de veces igual al número de elementos en el vector después de los elementos borrados.

Lanzamientos: nada a menos que el constructor de copias, el constructor de movimientos, el operador de asignación o el operador de asignación de movimientos arrojen una excepción T.

Como puede ver, las especificaciones de excepción para ambos son las mismas, pero std::vectorse menciona explícitamente que se llama al operador de asignación de movimiento.

También hay requisito para Tser MoveAssignablepara erase()trabajar con ambos std::vectory std::deque(Tabla 100), pero esto no implica la presencia del operador de asignación movimiento: se puede definir un operador de asignación de copia, y no definir operador de asignación movimiento, y esta clase será ser MoveAssignable.

Por si acaso, verifiqué con GCC y Clang, y de hecho std::vector::erase()llama al operador de asignación de copias si no hay un operador de asignación de movimiento, y std::deque::erase()hace lo mismo ( DEMO ).

Entonces la pregunta es: ¿me perdí algo, o este es un problema (editorial) en el estándar?

Actualización: He enviado un número de LWG # 2477 .

Anton Savin
fuente
14
Parece un defecto en el estándar.
Barry
44
^ ack. Un tema de LWG sería apropiado.
Columbo
44
Por lo general, el borrador del estándar es lo suficientemente bueno. Este es uno de esos casos en los que deberías mirar la cosa real.
Mark Ransom
3
@MarkRansom la fuente actual del estándar para std :: deque y std :: vector es la misma que en la pregunta, por lo que la probabilidad de que la versión final difiera es muy pequeña.
Anton Savin
3
N4141 tiene la misma redacción que N4140.
Brian

Respuestas:

9

En la reunión de Lenexa, el problema obtuvo el estado Inmediato con la resolución propuesta:

Esta redacción es relativa a N4296.

Cambie 23.3.3.4 [deque.modifiers] / 5 a:

-5- Complejidad : el número de llamadas al destructor deT es el mismo que el número de elementos borrados, pero el número de llamadas al operador deT asignación de no es mayor que el menor número de elementos antes de los elementos borrados y Número de elementos después de los elementos borrados.

Cambie 23.3.6.5 [vector.modifiers] / 4 a:

-4- Complejidad : El destructor de Tse llama el número de veces igual al número de elementos borrados, pero el operador de asignación de movimiento de Tse llama el número de veces igual al número de elementos en el vector después de los elementos borrados.

Es decir, si se acepta la resolución, no habrá mención especial de la asignación de movimiento std::vector::erase, y también std::deque::erasese aclarará un poco la redacción de .

Anton Savin
fuente