Sto cercando di inserire una copia di un elemento vector
esistente per raddoppiarlo. Il seguente codice ha funzionato nelle versioni precedenti, ma non riesce in Visual Studio 2010.Come inserire un elemento duplicato in un vettore?
#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;
}
uscita è -17891602 1 2
, previsto 1 1 2
.
Ho capito perché sta accadendo: il vettore viene riallocato e il riferimento diventa non valido prima di essere copiato nel punto di inserimento. Il Visual Studio precedente apparentemente faceva le cose in un ordine diverso, dimostrando così che un possibile risultato di comportamento indefinito è quello di funzionare correttamente e anche dimostrare che non è mai qualcosa su cui dovresti fare affidamento.
Ho trovato due modi diversi per risolvere questo problema. Uno è quello di utilizzare reserve
per assicurarsi che nessun riassegnazione avviene:
test.reserve(test.size() + 1);
test.insert(test.begin(), test[0]);
L'altro è quello di fare una copia del riferimento in modo che non c'è dipendenza dal riferimento rimangono validi:
template<typename T>
T make_copy(const T & original)
{
return original;
}
test.insert(test.begin(), make_copy(test[0]));
Anche se entrambi funzionano, nessuno dei due sembra una soluzione naturale. C'è qualcosa che mi manca?
BTW vc11 dev preview fornisce '1 1 2' per il primo esempio. –
@Jesse, questo non mi sorprende. È stato selezionato il sovraccarico Rvalue di 'insert' che sembra un bug che potrebbero aver risolto. Il codice è completamente diverso tra quel sovraccarico e quello che prende un riferimento const. –
Il casting su int funziona? –