C++ 我是否保证指向std::vector元素的指针在向量移动后有效?

C++ 我是否保证指向std::vector元素的指针在向量移动后有效?,c++,c++11,vector,stl,move,C++,C++11,Vector,Stl,Move,考虑到这个例子: std::vector<int> v1 = { 1, 2, 3 }; const int* i = &v1[1]; std::vector<int> v2(std::move(v1)); std::cout << *i << std::endl; std::vector v1={1,2,3}; 常量int*i=&v1[1]; std::vector v2(std::move(v1)); 标准::cout规定: 。。。可以

考虑到这个例子:

std::vector<int> v1 = { 1, 2, 3 };
const int* i = &v1[1];
std::vector<int> v2(std::move(v1));
std::cout << *i << std::endl;
std::vector v1={1,2,3};
常量int*i=&v1[1];
std::vector v2(std::move(v1));
标准::cout规定:

。。。可以选择(但不是必需的)移动 争论

看起来,
std::move
只是向库提示,通过转移所有权进行优化是可能的,但是否进行优化取决于库

这意味着您应该假设所有指向元素的指针在移动后都无效。

这是[我的重点]

应该(通常)需要移动容器来保留迭代器 [……]

[斯蒂芬·T·拉瓦维]
23.2.1[container.requirements.general]/10指出,除非另有规定,“任何swap()函数都不会使任何引用、指针、, 或迭代器,它引用正在处理的容器的元素 swapped.[注意:end()迭代器不引用任何元素,因此 它可能无效。-结束注释]”但是,移动构造函数和 移动分配操作符没有给出类似的失效 担保。担保需要几个例外,所以我不需要 除非另有规定,否则请相信像/11“这样的笼统语言 (明确地或通过根据其他函数定义函数) 函数),调用容器成员函数或传递 容器作为库函数的参数不应无效 迭代器,或更改该容器中对象的值。“ 这是适用的

[2014-02-13 Issaquah]

关于意图、若干措辞细节和附加段落的一般协议。

STL将提供最新的措辞移动到打开位置。

拟议决议:

[……]

容器的任何移动构造函数[…](数组除外)都不会使引用源容器元素的任何引用、指针或迭代器无效。[注意:
end()
迭代器没有引用任何元素,因此它可能无效。-结束注意]


因此,这是一个悬而未决的问题,对其基本解决方案(指针不应因移动而失效)有着广泛的共识。但是,它还没有被正式接受为缺陷。据我所知,所有主要的实现在移动构造时都不会使指针无效,而且这似乎是一种通常(隐式)提供的保证。

如果标准没有对此做任何说明,那么我猜它是依赖于实现的。N3797中的表99说明
X(rv)
,即从右值构造容器,必须具有恒定的复杂性(相对于复制构造的线性),我认为我们可以由此推断,元素在移动后必须驻留在相同的内存位置。然而,这并不一定意味着迭代器保持有效,我不认为在这种情况下它是有保证的,但是如果你改为
std::vector v2;v2.互换(v1)那么肯定是这样。(23.2.1/10)也就是说,请参见LWG 2321中的@gd1:“容器的任何移动构造函数[…](除了
数组
)都不会使引用源容器元素的任何引用、指针或迭代器无效。”这完全忽略了
std::move
的要点。是的,
std::move
有效地作为对其他函数的提示。它允许使用
向量(向量&)
构造函数
move
对该构造函数没有任何要求,但标准对其有要求,这就是问题所在。“如果参数标识了一个拥有资源的对象,这些重载可以选择(但不是必需的)移动参数所持有的任何资源。”它说不需要移动移动对象中的所有资源。我想知道,如果一个移动构造函数不想移动对象中的资源(并进行优化),为什么它首先要有一个移动构造函数?@mohammadb可能是因为它是由编译器自动生成的,可能是因为该类必须与具有更多功能的move构造函数的实现ABI兼容,该类甚至可能没有move构造函数,并且即使使用了
std::move
C(const C&)
copy构造函数最终被使用。@mohammadb
std::vector
的大多数实现不会移动资源对象(容器的每个元素);他们只是交换一个指针(移动所有权)。这很有趣也很有用,谢谢。我可能最终会使用
swap
,因为它显然保证了迭代器(因此,我猜,指针)的有效性。谢谢。在我的实际场景中,使用
swap
可以很容易地规避这个问题,我可能会继续使用这个解决方案。不过,这些信息非常有用,而且很高兴知道有些人正在研究这类问题。