Ultimamente sto giocando con i riferimenti Rvalue e ho riscontrato uno strano problema. Definiamo qualche semplice classe denominata Foo che contiene un vector<int>
:Utilizzo del riferimento di rvalore negli elenchi di inizializzazione
class Foo
{
public:
Foo(std::vector<int>&& v)
: v_(v)
{}
private:
std::vector<int> v_;
};
Un'istanza Foo
può essere costruito passando un vector<int>
temporanea come questa:
std::vector<int> temp;
Foo(std::move(temp));
Ora, quando ho cercato di passare da questo codice , Ho notato che il vettore all'interno di è costruito usando il costruttore di copia invece del costruttore di movimento. Tuttavia, se specifico il costruttore questo modo:
Foo(std::vector<int>&& v)
: v_(std::move(v))
{}
Quindi, lo spostamento costruttore dell'organo v_
è opportunamente chiamato. Perchè è così? Perché è necessario il numero ridondante std::move(v)
nell'elenco di inizializzazione? Perché il compilatore non è in grado di dedurre l'intento di chiamare il vettore costruttore di movimento poiché l'argomento relativo al costruttore viene specificato come riferimento Rvalue?
A proposito, sto usando GCC 4.6 con l'opzione -std = C++ 0x.
Grazie per il vostro aiuto. PMJ
Quindi è possibile ottenere lo stesso effetto (sebbene con 1 altra chiamata del costruttore di movimento) semplicemente prendendo l'oggetto in base al valore. Il chiamante usa 'std :: move', e il costruttore usa' std :: move'. 2 costruttori, ma nessuna allocazione. –
@Bo Persson: Grazie la risposta chiara. Non avevo pensato al problema derivante dal fare riferimento all'argomento Rvalue più volte. @ Nicol Bolas: non sono sicuro di aver capito il tuo punto, potresti fornire qualche esempio per favore? Grazie. – pmjobin