Copiar / mover a atribuição em std :: vector :: erase () e std :: deque :: erase ()

135

No processo de responder a outra pergunta, me deparei com formulações ligeiramente diferentes para std::vector::erase()e std::deque::erase().

Isto é o que C ++ 14 diz sobre std::deque::erase( [deque.modifiers]/4-6ênfase minha):

Efeitos: ...

Complexidade: o número de chamadas para o destruidor é igual ao número de elementos apagados, mas o número de chamadas para o operador de atribuição não é maior que o menor número de elementos Antes dos elementos apagados e o número de elementos após o elementos apagados.

Lança: nada, a menos que uma exceção seja lançada pelo construtor de cópias, mova o construtor, o operador de designação ou o operador de designação de T.

E aqui está o que diz sobre std::vector::erase( [vector.modifiers]/3-5):

Efeitos: ...

Complexidade: o destruidor de Té chamado o número de vezes igual ao número de elementos apagados, mas o operador de atribuição de movimento de Té chamado o número de vezes igual ao número de elementos no vetor após os elementos apagados.

Lança: nada, a menos que uma exceção seja lançada pelo construtor de cópias, mova o construtor, o operador de designação ou o operador de designação de T.

Como você pode ver, as especificações de exceção para os dois são as mesmas, mas std::vectoré explicitamente mencionado que o operador de atribuição de movimentação é chamado.

Há também necessidade de Tser MoveAssignablepara erase()trabalhar com ambos std::vectore std::deque(Tabela 100), mas isso não implica a presença do operador movimento atribuição: pode-se definir um operador de atribuição de cópia, e não definir movimento operador de atribuição, e esta classe vai ser MoveAssignable.

Por precaução, verifiquei com o GCC e o Clang e, de fato, chamo o std::vector::erase()operador de atribuição de cópias, se não houver um operador de atribuição de movimentação, e std::deque::erase()faça o mesmo ( DEMO ).

Portanto, a pergunta é: eu perdi alguma coisa ou esta é uma questão (editorial) no padrão?

Atualização: enviei um problema LWG nº 2477 .

Anton Savin
fonte
14
Parece um defeito no padrão.
Barry
4
^ ack. Um problema de LWG seria apropriado.
Columbo
4
Geralmente, o rascunho da norma é bom o suficiente. Este é um daqueles casos em que você deve observar a coisa real.
Mark Ransom
3
@ MarkRansom a fonte atual do padrão para o vetor std :: deque e std :: é a mesma da pergunta, portanto a probabilidade de a versão final diferir é muito pequena.
Anton Savin
3
N4141 tem a mesma redação que N4140.
Brian

Respostas:

9

Na reunião da Lenexa, a questão obteve status imediato com a proposta de resolução:

Esta redação é relativa ao N4296.

Altere 23.3.3.4 [deque.modifiers] / 5 para:

-5- Complexidade : O número de chamadas para o destruidor deT é o mesmo que o número de elementos apagados, mas o número de chamadas para o operador de atribuição deT não mais do que a menor do número de elementos é, antes dos elementos apagados e o número de elementos após os elementos apagados.

Altere 23.3.6.5 [vector.modifiers] / 4 para:

-4- Complexidade : O destruidor de Té chamado o número de vezes igual ao número de elementos apagados, mas o operador de atribuição de movimento de Té chamado o número de vezes igual ao número de elementos no vetor após os elementos apagados.

Ou seja, se a resolução for aceita, não haverá menção especial à designação da mudança std::vector::erasee também o texto std::deque::eraseserá esclarecido um pouco.

Anton Savin
fonte