std :: vector :: swap会使迭代器失效吗?

Mar*_* Ba 39 c++ iterator stl visual-c++

如果我交换两个向量,它们的迭代器是否仍然有效,现在只是指向"其他"容器,或者迭代器是否会失效?

那是,给定:

using namespace std;
vector<int> x(42, 42);
vector<int> y;
vector<int>::iterator a = x.begin(); 
vector<int>::iterator b = x.end();

x.swap(y);

// a and b still valid? Pointing to x or y?
Run Code Online (Sandbox Code Playgroud)

似乎std没有提到这个:

[n3092 - 23.3.6.2]

void swap(vector<T,Allocator>& x);

效果:将*的内容和容量()与x的内容和容量()进行交换.

请注意,因为我在VS 2005上,我也对迭代器调试检查等的影响感兴趣(_SECURE_SCL)

Jam*_*lis 29

在C++ 11中,交换的行为已经大大澄清,很大程度上允许标准库算法使用参数相关查找(ADL)来查找用户定义类型的交换函数.C++ 11添加了一个可交换的概念(C++11§17.6.3.2[swappable.requirements])以使其合法(并且是必需的).

解决您的问题的C++ 11语言标准中的文本是容器要求中的以下文本(§23.2.1[container.requirements.general]/8),它定义swap了容器成员函数的行为:

在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素.

未指定a.end()在交换之前具有值的迭代器在交换之后是否具有值b.end().

在您的示例中,a保证在交换后有效,但b不是因为它是结束迭代器.终止迭代器不能保证有效的原因在§23.2.1/ 10的注释中解释:

[注意:end()迭代器不引用任何元素,因此它可能无效. - 后注]

这与C++ 03中定义的行为相同,只是基本澄清了.C++ 03的原始语言是C++03§23.1/ 10:

no swap()函数使任何引用,指针或迭代器无效,引用被交换的容器的元素.

它在原始文本中并不是立即显而易见的,但是"对容器的元素"这一短语非常重要,因为end()迭代器不指向元素.

  • 带有end()迭代器的部分在std中确实有点蹩脚,因为正如这个例子所示,我必须为所有可能是end()的迭代器引入特殊的检查逻辑.另一方面,因为它只适用于VC++,我想我现在可以忍受这个. (2认同)

Ste*_*end 13

交换两个向量不会使迭代器,指针和对其元素的引用无效(C++ 03,23.1.11).

通常,迭代器将包含其容器的知识,并且交换操作为给定的迭代器维护它.

在VC++ 10中,使用此结构管理向量容器<xutility>,例如:

struct _Container_proxy
{   // store head of iterator chain and back pointer
    _Container_proxy()
    : _Mycont(0), _Myfirstiter(0)
    {   // construct from pointers
    }

    const _Container_base12 *_Mycont;
    _Iterator_base12 *_Myfirstiter;
};
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在 n3092 草案中,§23.2.1/9 中提出了要求:“在交换之前引用一个容器中的元素的每个迭代器都应在交换后引用另一个容器中的相同元素。” (2认同)