Скопировать/переместить назначение в std::vector:: erase() и std:: deque:: erase()
В процессе ответа на еще один вопрос я наткнулся на несколько разные формулировки для std::vector::erase()
и std::deque::erase()
.
Вот что говорит С++ 14 о std::deque::erase
([deque.modifiers]/4-6
, мой удар):
Эффекты:...
Сложность: количество вызовов деструктора совпадает с количеством стираемых элементов, но Количество вызовов оператора присваивания не больше, чем меньшее количество элементов Перед стираемыми элементами и количеством элементов после стираемых элементов.
Throws: Nothing, если исключение генерирует конструктор копирования, перемещает конструктор, оператор присваивания или оператор присваивания перемещения T
.
И вот что он говорит о std::vector::erase
([vector.modifiers]/3-5
):
Эффекты:...
Сложность: деструктор T
называется числом раз, равным количеству стираемых элементов, но оператор присваивания T
называется числом раз, равным количество элементов в векторе после стираемых элементов.
Throws: Nothing, если исключение генерирует конструктор копирования, перемещает конструктор, оператор присваивания или оператор присваивания перемещения T
.
Как вы можете видеть, спецификации исключений для обоих из них одинаковы, но для std::vector
он явно упоминает, что оператор присваивания перемещения вызывается.
Также для T
требуется MoveAssignable
для erase()
работать как с std::vector
, так и с std::deque
(таблица 100), но это не означает наличие оператора присваивания перемещения: один может определять оператор присваивания копий, а не определять оператор присваивания перемещения, а этот класс будет MoveAssignable
.
На всякий случай, я проверил с GCC и Clang, и действительно std::vector::erase()
вызывает оператор присваивания копии, если нет оператора присваивания перемещения, а std::deque::erase()
делает то же самое (DEMO).
Итак, вопрос: я что-то пропустил, или это (редакционная) проблема в стандарте?
Update:
Я отправил LWG issue # 2477.
Ответы
Ответ 1
На конференции Lenexa проблема получила немедленный статус с предлагаемым разрешением:
Эта формулировка относится к N4296.
Изменить 23.3.3.4 [deque.modifiers]/5:
-5- Сложность: количество вызовов деструктора из T
совпадает с количеством стираемых элементов, но количество вызовов оператора присваивания из T
- это не более чем меньшее количество элементов перед стираемыми элементами и количество элементов после стираемых элементов.
Изменить 23.3.6.5 [vector.modifier]/4:
-4- Сложность: деструктор T
называется числом раз, равным числу стираемых элементов, но оператор присваивания move T
называется числом раз, равное количеству элементов в векторе после стираемых элементов.
То есть, если разрешение принято, особого упоминания о назначении перемещения для std::vector::erase
не будет, а также формулировка для std::deque::erase
будет
немного уточнили.