c++ - 移动 vector 是否会使迭代器无效?

标签 c++ iterator c++11

如果我有一个指向 vector a 的迭代器,那么我从 a 移动构造或移动分配 vector b,该迭代器是否仍然指向同一个元素(现在在 vector b 中)?这就是我在代码中的意思:

#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; // Is a_iter valid here?
    return 0;
}

a_iter 是否仍然有效,因为 a 已被移动到 b 中,还是迭代器因移动而失效?作为引用,std::vector::swap does not invalidate iterators .

最佳答案

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


我在标准中找不到任何引用明确指出move 之前存在的迭代器在 move 之后 仍然有效.

从表面上看,假设 iterator 似乎是完全合理的。 通常被实现为指向受控序列的指针。如果是这种情况,那么迭代器在 move 之后仍然有效。 .

但是执行一个iterator是实现定义的。意思是,只要 iterator在特定平台上满足标准规定的要求,它可以以任何方式实现。理论上,它可以实现为返回 vector 的指针的组合。类和索引。如果,那么迭代器将在 move 之后变得无效。 .

是否 iterator这种方式实际实现是无关紧要的。它可以以这种方式实现,因此没有标准的具体保证,即 move迭代器仍然有效,你不能假设它们是有效的。还要记住,在 swap 之后这样的迭代器保证。 .这在之前的标准中得到了明确的说明。也许这只是标准委员会的疏忽,在 move 之后没有对迭代器做出类似的澄清。 ,但无论如何都没有这样的保证。

因此,总而言之,您不能假设您的迭代器在 move 之后仍然很好。 .

编辑:

n3242 草案中的 23.2.1/11 指出:

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.

这可能会导致人们得出结论,迭代器在 move 之后是有效的。 ,但我不同意。在您的示例代码中,a_itervector 的迭代器a .在 move 之后,那个容器,a肯定已经改变了。我的结论是上述条款不适用于这种情况。

关于c++ - 移动 vector 是否会使迭代器无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11021764/

相关文章:

c++ - Cmake 将参数解析成代码

用 auto 定义的变量的 C++11 类型

c++ - 在指向 int 的指针上调用 delete

c++ - 使用C/C++(套接字)连接到Gmail SMTP服务器

c# - LINQ 的迭代器 block

c++ - 宏中的#value 是什么意思

c++ - 堆和栈内存是如何管理、实现和分配的

c++ - 为什么 cout.precision() 会增加 float 的精度?

python - 如何在python中合并两个数据结构

java - 增强的 for 语句如何用于数组,以及如何获取数组的迭代器?