考虑这个例子:
std::vector<int> v1 = { 1, 2, 3 };
const int* i = &v1[1];
std::vector<int> v2(std::move(v1));
std::cout << *i << std::endl;
尽管在许多STL实现中这可能会起作用,但我保证标准是在移动std::vector
时不执行重新分配,并且内部缓冲区支持v2
与使用的相同是v1
的一个?我无法在互联网上找到这些信息,也无法在标准本身上找到这些信息。
答案 0 :(得分:15)
这是LWG open issue 2321 [强调我的]
应该(通常)需要移动容器来保存迭代器
[...]
[Stephan T. Lavavej] 23.2.1 [container.requirements.general] / 10表示除非另有说明,“否swap()函数使任何引用,指针无效, 或迭代器引用容器的元素 交换。 [注意:end()迭代器不引用任何元素,所以 它可能会失效。 - 结尾注释]“。然而,移动构造函数和 移动赋值运算符没有给出类似的失效 担保。担保需要几个例外,所以我没有 相信一般的语言/ 11“除非另有说明 (明确地或通过定义其他的函数 函数),调用容器成员函数或传递一个 作为库函数参数的容器不得无效 迭代器,或更改该容器中对象的值。“ 是适用的。
[2014-02-13 Issaquah]
关于意图,一些措辞尼特和其他段落的一般意见。
STL提供更新的措辞。 移至开放。
提议的决议:
[...]
没有移动构造函数[...]的容器(
array
除外)使引用源容器元素的任何引用,指针或迭代器无效。 [注意:end()
迭代器不引用任何元素,因此可能无效。 - 结束记录]
所以,这是一个悬而未决的问题,对其基本解决方案有一般性的一致意见(指针不应通过移动无效)。但是,它不是正式接受(但是?)作为缺陷。据我所知,所有主要实现都不会在移动构造时使指针无效,而且它似乎是一般(隐式)提供的保证。
答案 1 :(得分:3)
...有移动任何资源的选项,但不是必需的 争论......
看起来std::move
只是向图书馆提示通过转让所有权进行优化是可能的,但是由图书馆决定是否进行优化。
这意味着您应该假设所有指向元素的指针在移动后都无效。