Estoy tratando de insertar una copia de un elemento vector
existente para duplicarlo. El siguiente código trabajó en las versiones anteriores, pero no en Visual Studio 2010.¿Cómo insertar un elemento duplicado en un vector?
#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;
}
salida es -17891602 1 2
, espera 1 1 2
.
He descubierto por qué está sucediendo: el vector se reasigna y la referencia deja de ser válida antes de copiarse en el punto de inserción. Aparentemente, el antiguo Visual Studio hizo las cosas en un orden diferente, lo que demuestra que un resultado posible del comportamiento indefinido es trabajar correctamente y también probar que nunca es algo en lo que debe confiar.
He encontrado dos formas diferentes de solucionar este problema. Uno es utilizar reserve
para asegurarse de que ninguna reasignación tiene lugar:
test.reserve(test.size() + 1);
test.insert(test.begin(), test[0]);
La otra es hacer una copia de la referencia por lo que no hay dependencia de la referencia sigue siendo válido:
template<typename T>
T make_copy(const T & original)
{
return original;
}
test.insert(test.begin(), make_copy(test[0]));
Aunque ambos funcionan, ninguno se siente como una solución natural. ¿Se me escapa algo?
BTW vc11 dev preview da '1 1 2' para el primer ejemplo. –
@Jesse, eso no me sorprende. Se ha seleccionado la sobrecarga Rvalue de 'insert', que parece un error que podrían haber corregido. El código es completamente diferente entre esa sobrecarga y la que toma una referencia constante. –
¿Funciona el casting en int? –