通过调整大小缩小容器时,元素的销毁顺序

When shrinking a container via resize, in which order are the elements destroyed?

本文关键字:元素 顺序 小容器 调整 缩小      更新时间:2023-10-16

如果我有一个标准的C++容器std::vector<Bar>并且我通过调用小于当前.size()的大小.resize()来缩小它,那么多余的元素按什么顺序被销毁?

(如果可以找到两个不同的实现,则实现选择很有趣。

(这是受James Kanze评论的启发。

基于 2012 年 1 月的工作草案

2012 年 1 月的工作草案包含 C++11 标准以及少量的编辑更改。

资料来源,工作草案

对于vector


void resize(size_type sz); 效果:若sz <= size(),相当于erase(begin() + sz, end());。如果size() < sz,则追加 sz - size()序列中的值初始化元素。

vector::erase没有指定删除顺序。我希望它从begin() + szend()都是有序的,因为这对我来说是有道理的,但这只是我的期望。我在标准中找不到任何关于它的内容。

使用Visual Studio 2013分发的vector的实现似乎确实按照这个顺序擦除,MinGW的g ++ 4.8.1和g ++ 4.7.3(不是MinGW)也是如此。这些是我碰巧可以轻松访问的编译器。

在同一标准中,对于list


void resize(size_type sz); 1 效果:如果size() < sz,则将sz - size()值初始化的元素追加到序列中。如果sz <= size(),则相当于

list<T>::iterator it = begin();
advance(it, sz);
erase(it, end());


void resize(size_type sz, const T& c); 影响:

if (sz > size())
    insert(end(), sz-size(), c);
else if (sz < size()) {
    iterator i = begin();
    advance(i, sz);
    erase(i, end());
}
else
    ; // do nothing

然后,它继续指定绝对没有关于订购list::erase的任何有用信息。

使用Visual Studio 2013分发的list的实现似乎确实以相反的顺序擦除,而MinGW的g ++ 4.8.1和g ++ 4.7.3(不是MinGW)则没有。

基于撰写本文时的最新工作草案

工作草案

对于vector


void resize(size_type sz); 效果:如果sz <= size(),相当于调用pop_back() size() - sz次。如果size() < sz , 将sz - size()默认插入的元素追加到序列中。

这表示元素以相反的顺序删除。

对于list


void resize(size_type sz); 1 效果:如果size() < sz,则将sz - size()值初始化的元素追加到序列中。如果sz <= size(),则相当于

list<T>::iterator it = begin();
advance(it, sz);
erase(it, end());


void resize(size_type sz, const T& c); 影响:

if (sz > size())
    insert(end(), sz-size(), c);
else if (sz < size()) {
    iterator i = begin();
    advance(i, sz);
    erase(i, end());
}
else
    ; // do nothing

然后,它继续指定绝对没有关于订购list::erase的有用信息。

对于deque,标准指定的行为与vector相同。

除了 std::basic_stringstd::forward_list,该标准根据以下方面定义了resize erase(如果新大小小于原始大小),所以问题实际上是:erase( begin, end )是否指定任何销毁顺序。 而我所能做的在表 100 中找到这里,上面写着erase( q1, q2 )"擦除[q1, q2)范围内的元素"。 哪个(对我来说,在最少)仍然悬而未决:当标准使用表示法[q1, q2)(其中q1q2是迭代器),它是否暗示有序? 先验地,我认为不会。至少在<algorithms>部分中,它明确指出当操作必须有序时(以及它的事实在某些特定情况下明确说明它有点暗示在未指定的情况下不需要它)。

对于

它的价值:对于std::list<>::resize(),g++ 调用按升序删除;VS 按降序排列。 在这种情况下VS,这与 std::list<>::erase(这可能是合法的,如果销毁未指定,并且允许从一个调用到不同下一个)。

这取决于容器。例如,对矢量应用调整大小的效果如下

12 Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times

因此,对于向量,消除榄香的顺序从最后一个元素开始。

对于列表,方法是其他

效果:如果 size() <sz,则附加><= size(),则相当于 list::iterator 它 = 开始();前进(它,深圳);擦除(it, end());

但是没有说明元素被擦除的顺序。