2013-03-28 12 views
7

Jeśli się nie mylę, myślę, że zarówno odwołanie do wartości stałej, jak i odwołanie do wartości r mogą być powiązane z wartością r. Czy istnieje jakaś praktyczna różnica między funkcją, która zwraca poprzednią i funkcję, która zwraca tę ostatnią?Różnica między zwracaniem odniesienia do wartości stałej a wartością odniesienia

EDYCJA. Nie mogę zmienić tego pierwszego, ale dlaczego miałbym interesować się modyfikacją wartości? Czy jest sens?

+0

Tak, zgaduję. Będę edytować post ... – jbgs

+2

Jeśli mówisz o ** powrocie **, to prawdopodobnie nie chcesz zwrócić * referencji rvalue *. Chociaż może istnieć jakaś przypadek użycia, który mógłby zostać wdrożony przez zwrócenie wartości * rvalue-reference *, w większości sytuacji spowoduje to niezdefiniowane zachowanie. –

Odpowiedz

16

Numer referencyjny l można powiązać z dowolnym. Wartość rvalue reference może być powiązana tylko z wartościami rvalues ​​innych niż const.

  non-const lvalue const lvalue non-const rvalue const rvalue 
const T& yes    yes   yes    yes 
T&&   no     no    yes    no 

Jak widać, są bardzo różne.

Ponadto, jeśli wywołanie funkcji zwróci wartość odniesienia l, to wyrażenie jest lwartością, ale jeśli wywołanie funkcji zwraca referencję rwartości do obiektu, to wyrażenie jest wartością x.

Połączenie funkcja lwartością jeśli typ rezultacie lwartością typu odniesienia lub referencją RValue rodzaju funkcję, do xvalue jeśli typ wynik jest odniesienie RValue na typ obiektu, a prvalue inaczej.

Co do tego, kiedy chciałbyś zmodyfikować wartość rundy - cóż, właśnie o to chodzi w seansie ruchu. Rozważmy następujące wywołanie funkcji:

void func(std::string); 

func(std::string("Hello")); 

Wyrażenie std::string("Hello") jest rvalue że tworzy tymczasowy obiekt. Podczas inicjowania parametru std::string z tą wartością, wybierze konstruktora, który pobiera referencję rvalue - konstruktor ruchu. Konstruktor ten następnie kradnie rzeczy z wartości runtue, co jest zazwyczaj znacznie szybsze niż wykonanie pełnej kopii. Możemy go ukraść, ponieważ wiemy, że jest tymczasowy.

Co do kiedy należy zwrócić const referencje lwartości lub rvalue nazwy:

  • Zwracanie const lwartość odniesienia jest najczęściej stosowany, gdy chcesz dać dostęp do odczytu „wewnętrzne” obiekt (być może członkiem klasy), ale nie pozwalają go modyfikować.

  • Zwrot referencyjny rvalue jest najczęściej używany (w ogóle nie jest powszechny), gdy chcemy zezwolić na wywoływanie kodu, aby przejść z "wewnętrznego" obiektu (być może członka klasy). Zamiast przesuwania się z tymczasowo zwróconego obiektu (tak jak przy zwracaniu przez wartość), dosłownie przemieszczają się one z obiektu wewnętrznego.

    ten można także osiągnąć za pomocą nie- const odniesienia lwartości, ale wtedy musiałby wyraźnie std::move to.

Jest więc mało prawdopodobne, że będziesz musiał zwrócić referencję rvalue.

Nie oznacza to, że std::forward ma typ zwrotu, który wygląda jak T&&. Jest to jednak złudne, ponieważ może, ale nie musi być wartością rvalue, w zależności od typu T. Zobacz universal references.

+0

Uwaga boczna: Powiedziałbym, że dość rzadko program generuje wartości r "const". – Angew

+0

Dzięki. Ale czy istnieje jakiś praktyczny przypadek, w którym muszę zwrócić referencję rvalue? – jbgs

+0

OK, jeśli dobrze rozumiem, zwracanie wartości rvalue ma sens, gdy przekazuję to zwrócone odwołanie do innej funkcji, która ma na celu "kradzież" obiektu. – jbgs

1

Czy istnieje jakaś praktyczna różnica między funkcją, która zwraca poprzednią i funkcję, która zwraca tę ostatnią?

Pytanie wydaje się źle sformułowane. Funkcja, która zwraca stałą lwartości odniesienie zapewnia dostęp do obiektu tylko dla czytania, podczas gdy funkcja zwraca RValue odniesienie zapewnia dostęp ruchu co oznacza, że ​​abonent może mieć zawartość Spośród odesłany obiekt i przenieść go do innego obiektu. Nie można ich porównać w żaden sposób.

W obu przypadkach odniesienia muszą wskazywać obiekt, którego długość życia wykracza poza koniec funkcji, która go zwraca, w przeciwnym razie wywołujący wywoła niezdefiniowane zachowanie podczas korzystania z tego odniesienia.

Powiązane problemy