如果我有一个指向 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
可能是合理的在 move
之后 s 仍然有效,我认为标准实际上并不能保证这一点。因此,迭代器在 move
之后处于未定义状态。 .
我在标准中没有找到特别指出迭代器存在于 move
之前的引用资料在 move
之后 仍然有效.
从表面上看,假设 iterator
似乎是完全合理的通常实现为指向受控序列的指针。如果是这样,那么迭代器在 move
之后仍然有效。 .
但是执行一个iterator
是实现定义的。意思是,只要iterator
在特定平台上满足标准规定的要求,它可以以任何方式实现。从理论上讲,它可以作为返回 vector
的指针的组合来实现。类以及索引。如果是这种情况,那么迭代器将在 move
之后变得无效。 .
是否 iterator
实际上以这种方式实现是无关紧要的。它可以通过这种方式实现,因此没有标准的具体保证,即 move
迭代器仍然有效,你不能假设它们是。还请记住,在 swap
之后 迭代器有这样的保证。 .这在以前的标准中得到了特别的澄清。也许这只是 Std 委员会的疏忽,没有在 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_iter
是 vector
的迭代器a
. move
之后,那个容器,a
当然已经改变了。我的结论是上述条款不适用于本案。
关于c++ - 移动 vector 会使迭代器无效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40244743/