2013-06-27 13 views
10

Dla klas z włączonym przeniesieniem istnieje różnica między tymi dwoma elementami?Przekaż wartość lub 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)); 
} 

moim rozumieniu jest to, że jeśli używasz lwartość myvec również zobowiązane do wprowadzenia const Vectype& wersję Foo::bar() od Vectype&& nie zwiąże. Poza tym, w przypadku rvalue, Foo::bar(Vectype) skonstruuje wektor za pomocą konstruktora ruchu lub jeszcze lepiej zlikwiduje kopię razem, widząc, że vec jest rwartością (czyżby?). Czy istnieje zatem nieodparty powód, aby nie preferować deklaracji wartości zamiast przeciążeń lwartości i rwartości? (Rozważ, muszę w każdym przypadku skopiować wektor do zmiennej składowej).

+0

przed jakimkolwiek pedanterią Wiem, że przeciążenia są niejednoznaczne. –

Odpowiedz

3

Funkcja przekaż wartość jest wystarczająca (i równoważna), o ile typ argumentu ma wydajny konstruktor ruchu, co w tym przypadku jest prawdziwe w przypadku std::vector.

W przeciwnym razie użycie funkcji "przekaż wartość" może wprowadzić dodatkową konstrukcję kopii w porównaniu do korzystania z funkcji pass-by-rvalue-ref.

Zobacz odpowiedź https://stackoverflow.com/a/7587151/1190077 na powiązane pytanie Do I need to overload methods accepting const lvalue reference for rvalue references explicitly?.

2

Tak, pierwszy (Vectype&& vec) nie zaakceptuje obiektu const lub po prostu lwartości.

Jeśli chcesz zapisać obiekt w środku, tak jak to robisz, najlepiej skopiować (lub przesunąć, jeśli przekazujesz wartość rwartową) w interfejsie, a następnie przenieść, tak jak w drugim przykładzie.

5

Wersja pass-by-value dopuszcza argument l-wartości i tworzy jego kopię. Wersja rvalue-reference nie może zostać wywołana z argumentem lvalue.

Zastosowanie const Type& kiedy nie trzeba zmienić lub skopiować argument w ogóle, stosowanie przejść przez wartość, gdy chcesz wartość modyfikowalna, ale nie obchodzi mnie, jak go pobrać i używać Type& i Type&& przeciążeń gdy chcesz, żeby coś się zmieniło w zależności od kontekstu.

Powiązane problemy