2013-06-27 12 views
10

Per le classi abilitate allo spostamento esiste una differenza tra queste due?Passaggio per valore o rvalue-ref

struct Foo { 
typedef std::vector<std::string> Vectype; 
Vectype m_vec; 
//this or 
void bar(Vectype&& vec) 
{ 
    m_vec = std::move(vec); 
} 
//that 
void bar(Vectype vec) 
{ 
    m_vec = std::move(vec); 
} 
}; 
int main() 
{ 
    Vectype myvec{"alpha","beta","gamma"}; 
    Foo fool; 
    fool.bar(std::move(myvec)); 
} 

mia comprensione è che se si utilizza un valore assegnabile myvec avete richiesto inoltre di introdurre const Vectype& versione di Foo::bar() dal Vectype&& non si legano. A parte questo, nel caso di validità, Foo::bar(Vectype) costruirà il vettore usando il costruttore di mosse o meglio ancora eliderà la copia tutti insieme vedendo che vec è un valore rvalore (sarebbe?). Quindi c'è una ragione convincente per non preferire la dichiarazione del valore invece dei sovraccarichi lvalue e rvalue? (Considera necessario copiare il vettore nella variabile membro in ogni caso.)

+0

prima di ogni pedanteria, so che i sovraccarichi sono ambigui. –

risposta

3

La funzione pass-by-value è sufficiente (e equivalente), purché il tipo di argomento abbia un costruttore di spostamento efficiente, che in questo caso è vero per std::vector.

In caso contrario, l'utilizzo della funzione del valore di trasmissione può introdurre una costruzione di copia aggiuntiva rispetto all'utilizzo della funzione di riferimento del valore di riferimento.

Vedere la risposta https://stackoverflow.com/a/7587151/1190077 alla domanda correlata Do I need to overload methods accepting const lvalue reference for rvalue references explicitly?.

2

Sì, il primo (Vectype&& vec) non accetta un oggetto const o semplicemente lvalue.

Se si desidera salvare l'oggetto all'interno come si fa, è meglio copiare (o spostare se si passa un rvalue) nell'interfaccia e quindi spostarsi, proprio come nel secondo esempio.

5

La versione del valore passato consente un argomento lvalue e ne fa una copia. La versione di riferimento rvalore non può essere chiamata con un argomento lvalue.

Usa const Type& quando non è necessario modificare o copiare l'argomento a tutti, uso pass-by-valore quando si desidera un valore modificabile, ma non si cura come si ottiene, e utilizzare Type& e Type&& sovraccarichi quando vuoi qualcosa di leggermente diverso da accadere a seconda del contesto.

Problemi correlati