我正在尝试插入现有vector元素的副本以使其加倍.以下代码在以前的版本中有效,但在Visual Studio 2010中失败.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> test;
test.push_back(1);
test.push_back(2);
test.insert(test.begin(), test[0]);
cout << test[0] << " " << test[1] << " " << test[2] << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
-17891602 1 2预期产出1 1 2.
我已经弄清楚它为什么会发生 - 向量被重新分配,并且引用在被复制到插入点之前变为无效.较旧的Visual Studio显然以不同的顺序执行操作,从而证明未定义行为的一个可能结果是正确工作并且证明它永远不是您应该依赖的东西.
我想出了两种不同的方法来解决这个问题.一种方法是reserve确保不进行重新分配:
test.reserve(test.size() + 1);
test.insert(test.begin(), test[0]);
Run Code Online (Sandbox Code Playgroud)
另一种是从引用中复制,以便不依赖于引用的剩余有效:
template<typename T>
T make_copy(const T & original)
{
return original;
}
test.insert(test.begin(), make_copy(test[0]));
Run Code Online (Sandbox Code Playgroud)
虽然两者都有效,但两者都不是一种天生的解决方案.有什么我想念的吗?
C++标准在哪里声明传递给它的迭代器对std::vector::insert不能与原始序列重叠?
编辑:详细说明,我很确定标准不需要标准库来处理这样的情况:
std::vector<int> v(10);
std::vector<int>::iterator first = v.begin() + 5;
std::vector<int>::iterator last = v.begin() + 8;
v.insert(v.begin() + 2, first, last);
Run Code Online (Sandbox Code Playgroud)
但是,我无法在标准中找到任何可以禁止范围[first, last)和[v.begin(), v.end())重叠的内容.