Я пытаюсь вставить копию существующего элемента 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, по-видимому, делала что-то в другом порядке, доказывая тем самым, что один из возможных результатов поведения undefined заключается в том, чтобы работать правильно, а также доказывая, что он никогда не должен полагаться на него.
Я придумал два разных способа решить эту проблему. Один из них - использовать 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]));
Хотя оба работают, никто не чувствует себя естественным решением. Что-то мне не хватает?