通过调整大小缩小容器时,元素的排序是什么?

时间:2014-04-04 13:10:00

标签: c++

如果我有一个标准的C ++容器std::vector<Bar>,我通过调用.resize()来缩小它,其大小小于当前的.size(),那么多余的元素会被破坏?

(如果你能找到两个不同的实现,那么实现选择很有意思。)

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

3 个答案:

答案 0 :(得分:14)

基于2012年1月的工作草案

  

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

Sourceworking draft

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 E ff ects:如果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);
  ËFF学分:

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)则没有。

根据撰写本文时的最新工作草案

Working draft

vector

  

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

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

list

  

void resize(size_type sz);
  1 E ff ects:如果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);
  ËFF学分:

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相同。

答案 1 :(得分:5)

std::basic_string和{。}除外 std::forward_list,标准定义resize erase(如果新尺寸小于。erase( begin, end ) 原始大小),所以问题是:erase( q1, q2 )指定任何破坏顺序。而我所能做的一切 在这里找到表100,其中表示[q1, q2) &#34;删除[q1, q2)&#34;范围内的元素。哪个(对我来说,在 至少)仍然提出问题:标准使用时 符号q1(其中q2<algorithms>是迭代器), 这是否意味着有序或不顺序?先验,我想不会。 至少在std::list<>::resize()部分,它明确指出 当操作必须按顺序时(以及它的事实) 在某些特定情况下明确指出它有点暗示 在没有指定的情况下不需要它。

对于它的价值:对于std::list<>::erase,g ++调用 按升序删除; VS按降序排列。在这种情况下 对VS来说,这与破坏的顺序不同 {{1}}(如果是,则可能是合法的 破坏是未指定的,并允许从一次通话变化 下一个)。

答案 2 :(得分:3)

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

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

因此,对于向量,元素的破坏顺序从最后一个元素开始。

对于列表,方法是其他

  

效果:如果size()&lt; sz,追加sz - size()默认插入元素   顺序。如果sz&lt; = size(),相当于list :: iterator it =   开始();推进(它,sz);擦除(它,结束());

但是没有什么能说明元素被删除的顺序。