Скопіювати / перемістити завдання в std :: вектор :: 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
^ ак. Випуск LWG був би відповідним.
Коламбо

4
Зазвичай проект стандарту досить хороший. Це один із тих випадків, коли слід дивитись на реальну річ.
Марк Викуп 11

3
@MarkRansom поточне джерело стандарту для std :: deque та std :: vector така ж, як у питанні, тому ймовірність того, що остаточна версія відрізняється, дуже мала.
Антон Савін

3
N4141 має те ж формулювання, що і N4140.
Брайан

Відповіді:


9

На засіданні Lenexa питання отримало негайний статус із запропонованим рішенням:

Це формулювання відносно N4296.

Змініть 23.3.3.4 [deque.modifiers] / 5 на:

-5- Складність : число звернень до деструкторами вT НЕ такому ж , як число елементів стертих, але кількість дзвінків оператора присвоювання зT не більше , ніж менше з числа елементів перед стертими елементами і кількість елементів після стираних елементів.

Змініть 23.3.6.5 [вектор.модифікатори] / 4 на:

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

Тобто, якщо резолюція буде прийнята, про присвоєння переміщення особливих згадок не буде std::vector::erase, а також формулювання для std::deque::eraseцього буде трохи уточнено.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.