Копирование / перемещение назначения в std :: vector :: erase () и std :: deque :: erase ()

135

В процессе ответа на другой вопрос я наткнулся на несколько иные формулировки для std::vector::erase()и std::deque::erase().

Вот что говорит C ++ 14 std::deque::erase( [deque.modifiers]/4-6выделение мое):

Эффекты: ...

Сложность: Количество вызовов к деструктору такое же, как и количество стертых элементов, но количество вызовов к оператору присваивания не более, чем меньшее количество элементов до стертых элементов и количество элементов после стертые элементы.

Броски: ничего, если исключение не выдается конструктором копирования, конструктором перемещения, оператором присваивания или оператором присваивания перемещения T.

И вот что это говорит о std::vector::erase( [vector.modifiers]/3-5):

Эффекты: ...

Сложность: Деструктор Tназывается число раз , равное числу элементов стертых, но оператор присваивания переход из Tназывается число раз , равное числу элементов в векторе после стертых элементов.

Броски: ничего, если исключение не выдается конструктором копирования, конструктором перемещения, оператором присваивания или оператором присваивания перемещения T.

Как видите, спецификации исключений для них обоих одинаковы, но для std::vectorних явно указано, что вызывается оператор присваивания перемещения.

Там также требование , Tчтобы быть MoveAssignableдля erase()работы как с std::vectorи std::deque(таблица 100), но это не означает присутствия оператора присваивания ход: можно определить оператор присваивания копии, а не определять оператор присваивания двигаться, и этот класс будет быть MoveAssignable.

На всякий случай я проверил с GCC и Clang, и действительно std::vector::erase()вызывает оператор присваивания копии, если нет оператора присваивания перемещения, и std::deque::erase()делает то же самое ( DEMO ).

Итак, вопрос: я что-то упустил, или это (редакционная) проблема в стандарте?

Обновление: я отправил вопрос LWG # 2477 .

Антон Савин
источник
14
Похоже, дефект в стандарте.
Барри
4
^ Ack. Вопрос LWG будет уместным.
Коломбо
4
Обычно проект стандарта достаточно хорош. Это один из тех случаев, когда вы должны смотреть на реальную вещь.
Марк Рэнсом
3
@MarkRansom текущий источник стандарта для std :: deque и std :: vector такой же, как и в вопросе, поэтому вероятность того, что окончательная версия отличается, очень мала.
Антон Савин
3
N4141 имеет ту же формулировку, что и N4140.
Брайан,

Ответы:

9

На собрании в Ленексе вопрос получил статус «Немедленный» с предлагаемым решением:

Эта формулировка относится к N4296.

Измените 23.3.3.4 [deque.modifiers] / 5 на:

-5- Сложность : число обращений к деструктору вT не таком же , как число элементов стертых, но количество звонков оператора присваивания изT не более , чем меньшее из числа элементов перед стертыми элементами и количество элементов после стертых элементов.

Измените 23.3.6.5 [vector.modifiers] / 4 на:

-4- Сложность : деструктор Tназывается количеством раз, равным количеству стертых элементов, а оператор присваивания перемещенияT называется числом раз, равным количеству элементов в векторе после стертых элементов.

То есть, если решение будет принято, не будет упоминания о назначении перемещения std::vector::erase, а также std::deque::eraseбудет уточнена формулировка для .

Антон Савин
источник