【发布时间】:2012-04-30 09:15:45
【问题描述】:
我正在尝试插入现有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;
}
输出为-17891602 1 2,预期为1 1 2。
我已经弄清楚为什么会发生这种情况 - 向量正在重新分配,并且引用在复制到插入点之前变得无效。较旧的 Visual Studio 显然以不同的顺序做事,因此证明未定义行为的一个可能结果是正常工作,也证明它绝不是您应该依赖的东西。
我想出了两种不同的方法来解决这个问题。一种是使用reserve 来确保不会发生重新分配:
test.reserve(test.size() + 1);
test.insert(test.begin(), test[0]);
另一种是从引用中复制一份,这样就不再依赖于保持有效的引用:
template<typename T>
T make_copy(const T & original)
{
return original;
}
test.insert(test.begin(), make_copy(test[0]));
虽然两者都有效,但都不是一个自然的解决方案。我有什么遗漏吗?
【问题讨论】:
-
BTW vc11 dev preview 为第一个示例提供
1 1 2。 -
@Jesse,这并不让我感到惊讶。正在选择
insert的右值重载,这似乎是他们可能已修复的错误。该重载与采用 const 引用的代码完全不同。 -
@MarkRansom: 这个bug report 好像是它。
-
@DanNissenbaum,不,它没有。转换为
const int &有效,但我认为这只是因为它导致它使用旧代码路径。这不是一个正确的解决方法。 -
我认为您的建议没有太多选择,您可以在插入之前取值,例如
int copy = test[0]; test.insert(test.begin(), copy);
标签: c++ visual-studio-2010 vector