Domanda

ho incontrato un problema quando passa riferimenti rvalue tornati da una profondità di più di 1.

struct Data {
 std :: vector <int> data;
 Data () {
  data .push_back (1);
 };

 Data (Data && d)
 : data (std :: move (d .data))
 {}
};

Data && foo () {
 Data d;
 return std :: move (d);
}

Data && bar () {
 return std :: move (foo ()); // Crashes in autogenerated code
}

Data && baz () {
 return foo (); // Crashes in Data move constructor.
}

Data && bop () {
 Data d = foo ();
    return std :: move (d); // Crashes in autogenerated code.
}

int main () {
 Data d_foo = foo (); // This is fine.
 Data d_bar = bar (); // Crash.
 Data d_bar = baz (); // Crash.
 Data d_bop = bop (); // Crash.
}

Credo che lo std :: vector è essere doppio liberato. Sto usando g ++ (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5

Funziona il codice qui sopra per voi? Sto facendo qualcosa di sbagliato o c'è un bug nella libreria o compilatore?

Se (il cielo forfend) è il compilatore (ci sono altri noti C ++ 0x bug nel GCC), Qualcuno può dirmi se c'è un modo apt-sicuro per l'aggiornamento o patch GCC su Ubuntu? Ho provato prima, ma ottenuto in un groviglio di pacchetti non supportati.

Grazie mille.

È stato utile?

Soluzione

Non c'è restituire un riferimento rvalue, ritorni un valore, che viene poi presa dal chiamante per riferimento come rvalue. Si dovrebbe solo avere Data foo(), non Data&& foo(). Il fatto che una di queste opere è puramente un caso, in quanto è un comportamento indefinito.

Altri suggerimenti

E raramente ha senso per i riferimenti di ritorno rvalue dalla funzione (eccezione std :: mossa), a causa di riferimento è stato presumibilmente legato a una temporanea, o di un oggetto sulla pila come nel vostro caso e quando sei tornato esso, l'oggetto è andato .

Modifica:

Data && foo () {
 Data d;
 return std :: move (d);
}

d viene distrutta quando si va fuori del campo di applicazione, in modo che stai tornando penzoloni di riferimento.

Non si può aspettare nulla di buono da restituire un && ad un oggetto locale non più di quanto di tornare un normale di riferimento / puntatore ad un oggetto locale.

Si dovrebbe tornare per valore. In C ++ 03 si tratta di una situazione in cui è consentito il compilatore di ottimizzare le chiamate verso via costruttore di copia. In C ++ 0x Ciò significa che (se la copia non può essere ottimizzata distanza - es compilatori non gestiscono quando restituisce un oggetto diverso da diversi rami) il costruttore mossa sarà invocata invece di un costruttore di copia (se presente) per ottenere il valore dalla funzione.

Per quanto posso capire, la semantica mossa dovrebbe calcio automaticamente in luoghi dove è sicuro, e rvalue tipi di parametri di riferimento consentono di determinare se l'argomento è un rvalue (qualcosa che si può esplicitamente spostare) oppure no.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top