Подтвердить что ты не робот

Порядок уничтожения элементов std::vector

Возможный дубликат:
Порядок уничтожения элементов контейнера STL

Есть ли гарантия, что элементы std::vector будут уничтожены от последнего до первого?

4b9b3361

Ответ 1

2003: 5.3.5/6 говорит о delete[]:

Выражение-выражение вызовет деструктор (если есть) для объекта или элементов удаляемого массива. В случае массива элементы будут уничтожены в порядке убывания адреса (то есть в обратном порядке завершения их конструктора, см. 12.6.2).

Итак, если ваш распределитель объектов std::vector использует delete[], тогда да, он должен уничтожать элементы в обратном порядке.

Однако нет никакой гарантии, что ваш std::vector будет работать таким образом (и, на самом деле, скорее всего, это не так), и я не могу найти никаких цитат, специфичных для контейнера.

Действительно, я думаю, что все это относится к вашему распределителю и 2003: 20.1.5 (в котором перечислены требования, предъявляемые к распределителям), похоже, ничего не говорит об этом.

Ответ 2

Они стандартно гарантируют это для необработанного массива, но я не могу найти ничего, что могло бы гарантировать его для контейнеров.

От [expr.delete] (новая формулировка для С++ 0x):

Если значение операнда выражения-удаления не является значением нулевого указателя, выражение-delete будет вызывать деструктор (если есть) для объекта или элементов удаляемого массива. В случае массив, элементы будут уничтожены в порядке убывания адреса (то есть в обратном порядке завершения их конструктора; см. 12.6.2).

std::vector (и на самом деле, все контейнеры в стандартной библиотеке, возможно исключая std::array), не используют delete[] для уничтожения элементов (они используют allocator_traits<allocator_type>::destroy для каждого элемента отдельно), поэтому вышеуказанная гарантия не применяется. И я не могу найти никаких ограничений для std::vector в частности или контейнеров в целом, порядка порядка удаления. Для некоторых контейнеров такая гарантия будет очень дорогой (например, std::forward_list не может перебирать элементы в обратном порядке, чтобы удалить их, а std::map не помнит порядок, в котором были добавлены пары).

Из [container.requirements.general] (формулировка С++ 0x):

Для компонентов, определенных в этом подпункте, объявляющих allocator_type, объекты, хранящиеся в этих компоненты должны быть построены с использованием функции allocator_traits:: construct и уничтожен с помощью функции allocator_traits:: destroy (20.6.8.2).

Ответ 3

Нет, существуют гарантии для массивов, где все элементы построены, упорядочены и уничтожены в обратном порядке. Это несколько согласуется с тем, как обрабатываются глобальные объекты.

С другой стороны, члены контейнера могут быть сконструированы и уничтожены в любом порядке, используя, например, функции-члены insert и erase. Чтобы быть несколько последовательными и уничтожать элементы в обратном порядке построения, это потребовало бы, чтобы контейнеры сохраняли какой-то журнал над этими изменениями. Очевидно, это было бы дорого!

Лучше всего, что деструктор контейнера вызывает clear(), который определяется как erase(begin(), end()), но я не могу найти никаких требований для этого. Стандарт только говорит "линейная сложность" в таблице 65.