保证重新排序矢量

Som*_*ken 10 c++ vector language-lawyer

说我有这个代码:

#include <iostream>
#include <vector>

int main() 
{
    std::vector<int> vec {10, 15, 20};
    auto itr = vec.begin();
    vec.erase(itr);
    for(const auto& element : vec)
    {
        std::cout << element << " ";
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给了我15 20预期的效果.现在,cppreference说erase():

在擦除点或之后使迭代器和引用无效,包括end()迭代器

很公平,但这是标准给出的唯一保证vector::erase()吗?

是否允许在擦除的迭代器之后重新排序它的元素?

例如,这些条件是否保证在擦除后保持,这意味着erase()迭代器之后的所有元素都向左移1:

vec[0] == 15
vec[1] == 20
Run Code Online (Sandbox Code Playgroud)

或者允许实现在他们认为合适的情况下移动值,从而创建场景vec[0] == 20等等?

我想引用标准的相关部分.

Sam*_*hik 13

让我们从头开始:

23.2.3序列容器

序列容器将所有相同类型的有限对象组织成严格的线性排列.该库提供了四种基本类型的序列容器:vector,forward_list,list和deque.

强调"严格的线性安排".这是明确的.

该定义之后是一个名为"序列容器要求"的表,它erase()因此描述:

a.erase(q) [ ... ]
Effects:  Erases the element pointed to by q
Run Code Online (Sandbox Code Playgroud)

结合起来,这没有留下解释的余地​​.向量中的元素始终处于"严格的线性排列"中,因此当其中一个元素为erase()d时,只有一个可能的结果.

  • 好吧,一些摆动的空间 - "严格线性"意味着什么,并且它在标准的其他地方指定:-)我宁愿说"按特定插入操作的顺序排序"或类似的东西. (3认同)

Lig*_*ica 7

从技术上讲,不,标准没有写出一个承诺,即你不会在最不期望的时候重新订购元素.

实际上,显然它不会那样做.那太荒谬了.

从法律上讲,你可以采取"效果"条款:

删除q指向的元素

除非另有说明,否则没有其他影响(例如迭代器失效,从擦除效果开始).