std :: vector :: swap invalidate迭代器吗?

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

也就是说,给出:

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? 

这似乎没有提到这一点:

[n3092 – 23.3.6.2]

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

效果:将* this的内容和容量()与x的内容和容量()交换。

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

在C ++ 11中,交换的行为已经得到了相当的澄清,在很大程度上允许标准库algorithm使用参数相关查找(ADL)为用户定义的typesfind交换函数。 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:

没有swap()函数使任何引用,指针或迭代器引用正在交换的容器的元素无效。

这在原文中并不明显,但“对容器元素”这个短语非常重要,因为end()迭代器不指向元素。

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

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

在VC ++ 10中,vector容器是使用<xutility>这个结构进行pipe理的,例如:

 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; }; 

所有引用容器元素的迭代器都保持有效

至于Visual Studio 2005,我刚刚testing过。 我认为它应该始终工作,因为vector :: swap函数甚至包含一个明确的步骤来交换一切:

  // vector-header void swap(_Myt& _Right) { // exchange contents with _Right if (this->_Alval == _Right._Alval) { // same allocator, swap control information #if _HAS_ITERATOR_DEBUGGING this->_Swap_all(_Right); #endif /* _HAS_ITERATOR_DEBUGGING */ ... 

迭代器指向现在交换的vector对象中的原始元素。 (例如,对于OP,他们首先指向x元素,在交换之后它们指向y元素。)

请注意,在n3092草案中,要求在§23.2.1/ 9中规定:

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