[英]Does std::vector::swap invalidate iterators?
如果我交换两个向量,它们的迭代器是否仍然有效,现在只是指向“其他”容器,或者迭代器是否会失效?
那是,给定:
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?
似乎std没有提到这个:
[n3092 - 23.3.6.2]
void swap(vector<T,Allocator>& x);
效果:将*的内容和容量()与x的内容和容量()进行交换。
请注意,因为我在VS 2005上,我也对迭代器调试检查等的影响感兴趣(_SECURE_SCL)
在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:
没有
swap()
函数使任何引用,指针或迭代器无效,引用被交换的容器的元素。
它在原始文本中并不是很明显,但是“对容器元素”这一短语非常重要,因为end()
迭代器不指向元素。
交换两个向量不会使迭代器,指针和对其元素的引用无效(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;
};
至于Visual Studio 2005,我刚刚测试过它。 我认为它应该始终有效,因为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 */
...
迭代器指向现在交换的矢量对象中的原始元素。 (即,对于OP,它们首先指向x
元素,在交换之后它们指向y
元素。)
请注意,在n3092草案中,要求在§23.2.1/ 9中列出:
在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.