简体   繁体   English

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

[英]Does std::vector::swap invalidate iterators?

If I swap two vectors, will their iterators remain valid, now just pointing to the "other" container, or will the iterator be invalidated? 如果我交换两个向量,它们的迭代器是否仍然有效,现在只是指向“其他”容器,或者迭代器是否会失效?

That is, given: 那是,给定:

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?

It seems the std mentions nothing about this: 似乎std没有提到这个:

[n3092 - 23.3.6.2] [n3092 - 23.3.6.2]

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

Effects: Exchanges the contents and capacity() of *this with that of x. 效果:将*的内容和容量()与x的内容和容量()进行交换。

Note that since I'm on VS 2005 I'm also interested in the effects of iterator debug checks etc. (_SECURE_SCL) 请注意,因为我在VS 2005上,我也对迭代器调试检查等的影响感兴趣(_SECURE_SCL)

The behavior of swap has been clarified considerably in C++11, in large part to permit the Standard Library algorithms to use argument dependent lookup (ADL) to find swap functions for user-defined types. 在C ++ 11中,交换的行为已经大大澄清,很大程度上允许标准库算法使用参数相关查找(ADL)来查找用户定义类型的交换函数。 C++11 adds a swappable concept (C++11 §17.6.3.2[swappable.requirements]) to make this legal (and required). C ++ 11添加了一个可交换的概念(C ++11§17.6.3.2[swappable.requirements])以使其合法(并且是必需的)。

The text in the C++11 language standard that addresses your question is the following text from the container requirements (§23.2.1[container.requirements.general]/8), which defines the behavior of the swap member function of a container: 解决您的问题的C ++ 11语言标准中的文本是容器要求中的以下文本(§23.2.1[container.requirements.general] / 8),它定义了容器的swap成员函数的行为。 :

Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap. 在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素。

It is unspecified whether an iterator with value a.end() before the swap will have value b.end() after the swap. 未指定在交换之前具有值a.end()的迭代器在交换之后是否具有值b.end()

In your example, a is guaranteed to be valid after the swap, but b is not because it is an end iterator. 在您的例子, a是保证交换后是有效的,但b不是因为它是一个结束迭代器。 The reason end iterators are not guaranteed to be valid is explained in a note at §23.2.1/10: 在第23.2.1 / 10号注释中解释了最终迭代器无法保证有效的原因:

[Note: the end() iterator does not refer to any element, so it may be invalidated. [注意: end()迭代器不引用任何元素,因此可能无效。 --end note] - 后注]

This is the same behavior that is defined in C++03, just substantially clarified. 这与C ++ 03中定义的行为相同,只是基本澄清了。 The original language from C++03 is at C++03 §23.1/10: C ++ 03的原始语言是C ++03§23.1/ 10:

no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. 没有swap()函数使任何引用,指针或迭代器无效,引用被交换的容器的元素。

It's not immediately obvious in the original text, but the phrase "to the elements of the containers" is extremely important, because end() iterators do not point to elements. 它在原始文本中并不是很明显,但是“对容器元素”这一短语非常重要,因为end()迭代器不指向元素。

Swapping two vectors does not invalidate the iterators, pointers, and references to its elements (C++03, 23.1.11). 交换两个向量不会使迭代器,指针和对其元素的引用无效(C ++ 03,23.1.11)。

Typically the iterator would contain knowledge of its container, and the swap operation maintains this for a given iterator. 通常,迭代器将包含其容器的知识,并且交换操作为给定的迭代器维护它。

In VC++ 10 the vector container is managed using this structure in <xutility> , for example: 在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;
};

As for Visual Studio 2005, I have just tested it. 至于Visual Studio 2005,我刚刚测试过它。 I think it should always work, as the vector::swap function even contains an explicit step to swap everything: 我认为它应该始终有效,因为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 */
 ...

The iterators point to their original elements in the now-swapped vector object. 迭代器指向现在交换的矢量对象中的原始元素。 (Ie w/rg to the OP, they first pointed to elements in x , after the swap they point to elements in y .) (即,对于OP,它们首先指向x元素,在交换之后它们指向y元素。)

Note that in the n3092 draft the requirement is laid out in §23.2.1/9 : 请注意,在n3092草案中,要求在§23.2.1/ 9中列出:

Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap. 在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: unique是否会使向量迭代器无效? - Does std::unique invalidate vector iterators? 带有状态分配器的 std::vector::swap() 是否应该使所有迭代器无效? - Should std::vector::swap() with stateful allocators invalidate all iterators? std :: vector :: reserve是否保证在这种情况下实现不会使迭代器失效? - Does std::vector::reserve guarantee that the implementation will not invalidate iterators in this case? pop_back() 真的会使 std::vector 上的 *all* 迭代器无效吗? - Does pop_back() really invalidate *all* iterators on an std::vector? 向量排序是否使迭代器无效? - Does a vector sort invalidate iterators? 移动向量会使迭代器无效吗? - Does moving a vector invalidate iterators? 调整向量大小会使迭代器无效吗? - Does resizing a vector invalidate iterators? 如果向量有足够的空间(通过储备创建),std :: vector :: insert()是否会使迭代器无效? - Does std::vector::insert() invalidate iterators if the vector has enough room (created through reserve)? 为什么std :: vector :: insert会在插入点之后使所有迭代器无效 - Why does std::vector::insert invalidate all iterators after the insertion point std::list::erase 不会使其他迭代器和引用无效 - std::list::erase does not invalidate other iterators and references
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM