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

时间:2014-08-17 08:39:22

标签: 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;

尽管在许多STL实现中这可能会起作用,但我保证标准是在移动std::vector时不执行重新分配,并且内部缓冲区支持v2与使用的相同是v1的一个?我无法在互联网上找到这些信息,也无法在标准本身上找到这些信息。

2 个答案:

答案 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)

cppreference.com声明:

  

...有移动任何资源的选项,但不是必需的   争论......

看起来std::move只是向图书馆提示通过转让所有权进行优化是可能的,但是由图书馆决定是否进行优化。

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