2013-07-30 8 views
14

Na stronie How to: Write a Move Constructor Microsoft ma przykład, jak napisać konstruktor ruchu. Jest to zasadniczo w postaci:std :: przenieś na zmienną, która już jest T &&

MyClass::MyClass(MyClass&& lhs) 
{ 
    *this = std::move(lhs); 
} 

Próbowałem i std::move naprawdę tutaj jest wymagana, ale dlaczego? Pomyślałem, że jedyną rzeczą, jaką zrobiłem, było przejście na T&&. Ale lhs jest już typu MyClass&&, czyż nie?

+14

nazwane referencje są lwartościami. *Zawsze*. –

+3

Jest długi, ale [to jest dobry odczyt] (http://thbecker.net/articles/rvalue_references/section_01.html), aby dowiedzieć się wszystkiego o referencjach rvalue. –

+0

R. Martino Fernandes: Dzięki! Zaakceptuję to jako odpowiedź. – Petter

Odpowiedz

20

Nazwane referencje rvalue są wartościami l. Nienazwane wartości rvalue są wartościami r. Jest to ważne, aby zrozumieć, dlaczego wywołanie std :: posunięcie jest konieczne: foo&& r = foo(); foo f = std::move(r);

Spójrz na to odpowiedź: https://stackoverflow.com/a/5481588/1394283 Wyjaśnia to bardzo dobrze.


Spójrz na tej funkcji:

void foo(X&& x) 
{ 
    X anotherX = x; 
    // ... 
} 

Interesującą pytanie brzmi: które przeciążenie X „s kopia konstruktora jest wywoływana w ciele foo? Tutaj x jest zmienną zadeklarowaną jako referencja rwartości. W związku z tym można się spodziewać, że samo x będzie wiązało się jak rwart, czyli powinno być wywoływane X(X&& rhs);.

Umożliwienie sematics move być stosowane w sposób dorozumiany do czegoś, co ma nazwę, jak w

X anotherX = x; 
// x is still in scope! 

byłoby niebezpiecznie kłopotliwe i podatne na błędy, ponieważ rzeczą, z której po prostu przeniósł się, że jest rzeczą, że po prostu skradziono, jest nadal dostępny na kolejnych liniach kodu. Ale całą semantyką ruchu było zastosowanie go tylko tam, gdzie "nie ma znaczenia" w tym sensie, że rzecz, z której się poruszamy, umiera i znika zaraz po przeprowadzce.

Dlatego projektanci odniesień rvalue wybrały rozwiązanie, które jest nieco bardziej subtelny niż:

rzeczy, które są zgłaszane jako odniesienie rvalue może być lwartościami lub rvalues. Kryterium wyróżniającym jest: , jeśli ma nazwę, to jest lwartością. W przeciwnym razie jest to rwalut.

Źródło: http://thbecker.net/articles/rvalue_references/section_05.html

+1

Aby być uczciwym, zwracana wartość 'T & foo()' nie ma nazwy, ale jest lwartością. – Yakk

+0

@Yakk Masz rację. _ ** Wartości ** o nienazwanej wartości ** są wartościami r. Tutaj mówimy tylko o wartościach r. –

Powiązane problemy