移动矢量是否无效迭代器? [英] Does moving a vector invalidate iterators?

查看:105
本文介绍了移动矢量是否无效迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个向量的迭代器,然后我从该向量移动构造或移动分配另一个向量,该迭代器仍指向新向量中的有效元素?这里有一个简单的例子:

If I have an iterator to a vector, then I move-construct or move-assign another vector from that vector, does that iterator still point to a valid element in the new vector? Here's a simple example:

#include <vector>
#include <iostream>

int main(int argc, char *argv[])
{
    std::vector<int>::iterator a_iter;
    std::vector<int> b;
    {
        std::vector<int> a{1, 2, 3, 4, 5};
        a_iter = a.begin() + 2;
        b = std::move(a);
    }
    std::cout << *a_iter << std::endl;
    return 0;
}

a_iter 有效,因为 a 已移动到 b ,或是移动无效的迭代器?作为参考, std :: vector :: swap 不会使迭代器无效

Is a_iter still valid since a has been moved into b, or is the iterator invalidated by the move? For reference, std::vector::swap does not invalidate iterators.

推荐答案

虽然可以合理地假设 iterator 移动后仍然有效,我不认为标准实际上保证这一点。因此,在 move 之后,迭代器处于未定义状态。

While it might be reasonable to assume that iterators are still valid after a move, I don't think the Standard actually guarantees this. Therefore, the iterators are in an undefined state after the move.

移动之前存在的迭代器在之后仍然有效的标准中没有可以找到的参考 / em> move

There is no reference I can find in the Standard which specifically states that iterators that existed before a move are still valid after the move.

从表面上看, code> iterator 通常实现为指向受控序列的指针。如果是这种情况,那么迭代器在 move 后仍然有效。

On the surface, it would seem to be perfectly reasonable to assume that an iterator is typically implemented as pointers in to the controlled sequence. If that's the case, then the iterators would still be valid after the move.

code> iterator 是实现定义的。意思是,只要特定平台上的迭代器满足标准提出的要求,它就可以以任何方式实现。理论上,它可以作为指针返回到向量类和索引的组合来实现。如果大小写,那么在 move 之后,迭代器就会无效。

But the implementation of an iterator is implementation-defined. Meaning, so long as the iterator on a particular platform meets the requirements set forth by the Standard, it can be implemented in any way whatsoever. It could, in theory, be implemented as a combination of a pointer back to the vector class along with an index. If that's the case, then the iterators would become invalid after the move.

是否一个迭代器实际上是这样实现是不相关的。它可以这样实现,所以没有从标准的特定保证后 - move 迭代器仍然有效,你不能假设他们是。还要注意 交换之后为迭代器提供此类保证。这从以前的标准中明确地澄清了。也许这只是一个标准委员会的监督,不能在移动后对迭代器做类似的澄清,但在任何情况下都没有这样的保证。

Whether or not an iterator is actually implemented this way is irrelevant. It could be implemented this way, so without a specific guarantee from the Standard that post-move iterators are still valid, you cannot assume that they are. Bear in mind also that there is such a guarantee for iterators after a swap. This was specifically clarified from the previous Standard. Perhaps it was simply an oversight of the Std comittee to not make a similar clarification for iterators after a move, but in any case there is no such guarantee.

因此,它的长短是你不能假设你的迭代器仍然是一个移动后仍然是好的。

Therefore, the long and the short of it is you can't assume your iterators are still good after a move.

草案n3242中的23.2.1 / 11说明:

23.2.1/11 in Draft n3242 states that:


除非另有说明(明确或通过其他函数定义
函数),调用容器成员
函数或传递容器作为参数到库函数
不会使迭代器无效,或更改该容器中的对象
的值。

Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.

这可能会导致一个结论:迭代器在移动后有效,但我不同意。在您的示例代码中, a_iter 向量的迭代器 a 。在 move 之后,该容器, a 肯定已更改。我的结论是上述条款不适用于这种情况。

This might lead one to conclude that the iterators are valid after a move, but I disagree. In your example code, a_iter was an iterator in to the vector a. After the move, that container, a has certainly been changed. My conclusion is the above clause does not apply in this case.

这篇关于移动矢量是否无效迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆