Возможный дубликат:
Порядок уничтожения элементов контейнера STL
Есть ли гарантия, что элементы std::vector
будут уничтожены от последнего до первого?
Возможный дубликат:
Порядок уничтожения элементов контейнера STL
Есть ли гарантия, что элементы std::vector
будут уничтожены от последнего до первого?
2003: 5.3.5/6 говорит о delete[]
:
Выражение-выражение вызовет деструктор (если есть) для объекта или элементов удаляемого массива. В случае массива элементы будут уничтожены в порядке убывания адреса (то есть в обратном порядке завершения их конструктора, см. 12.6.2).
Итак, если ваш распределитель объектов std::vector
использует delete[]
, тогда да, он должен уничтожать элементы в обратном порядке.
Однако нет никакой гарантии, что ваш std::vector
будет работать таким образом (и, на самом деле, скорее всего, это не так), и я не могу найти никаких цитат, специфичных для контейнера.
Действительно, я думаю, что все это относится к вашему распределителю и 2003: 20.1.5 (в котором перечислены требования, предъявляемые к распределителям), похоже, ничего не говорит об этом.
Они стандартно гарантируют это для необработанного массива, но я не могу найти ничего, что могло бы гарантировать его для контейнеров.
От [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).
Нет, существуют гарантии для массивов, где все элементы построены, упорядочены и уничтожены в обратном порядке. Это несколько согласуется с тем, как обрабатываются глобальные объекты.
С другой стороны, члены контейнера могут быть сконструированы и уничтожены в любом порядке, используя, например, функции-члены insert
и erase
. Чтобы быть несколько последовательными и уничтожать элементы в обратном порядке построения, это потребовало бы, чтобы контейнеры сохраняли какой-то журнал над этими изменениями. Очевидно, это было бы дорого!
Лучше всего, что деструктор контейнера вызывает clear()
, который определяется как erase(begin(), end())
, но я не могу найти никаких требований для этого. Стандарт только говорит "линейная сложность" в таблице 65.