na przykład:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
źródło
na przykład:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
To zwraca wiszące odniesienie, tak jak w przypadku odniesienia l-wartości. Po powrocie funkcji obiekt tymczasowy zostanie zniszczony. Powinieneś zwrócić Beta_ab
według wartości, jak poniżej
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Teraz poprawnie przenosi tymczasowy Beta_ab
obiekt do wartości zwracanej przez funkcję. Jeśli kompilator może, całkowicie uniknie tego ruchu, używając RVO (optymalizacja wartości zwracanej). Teraz możesz wykonać następujące czynności
Beta_ab ab = others.toAB();
I przeniesie konstrukcję tymczasową do ab
lub zrobi RVO, aby całkowicie pominąć wykonywanie ruchu lub kopiowania. Polecam przeczytanie BoostCon09 Rvalue References 101, które wyjaśniają sprawę i jak (N) RVO wchodzi z tym w interakcje.
Twój przypadek zwrócenia odwołania do wartości r byłby dobrym pomysłem w innych przypadkach. Wyobraź sobie, że masz getAB()
funkcję, którą często wywołujesz tymczasowo. Nie jest optymalne, aby zwracał referencję const lvalue dla tymczasowych wartości r. Możesz to zaimplementować w ten sposób
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Zauważ, że move
w tym przypadku nie jest opcjonalna, ponieważ ab
nie jest ani lokalną automatyczną, ani tymczasową wartością r. Teraz kwalifikator ref &&
mówi, że druga funkcja jest wywoływana na tymczasowych rvalue, wykonując następujący ruch zamiast kopiowania
Beta_ab ab = Beta().getAB();
To może być bardziej skuteczny, na przykład, w nieco innym kontekście:
template <typename T> T&& min_(T&& a, T &&b) { return std::move(a < b? a: b); } int main() { const std::string s = min_(std::string("A"), std::string("B")); fprintf(stderr, "min: %s\n", s.c_str()); return 0; }
Ciekawe jest to, że na moim komputerze
clang++ -O3
generuje 54 instrukcje dla powyższego kodu w porównaniu z 62 instrukcjami dla zwykłegostd::min
. Jednak wraz z-O0
nim generuje 518 instrukcji dla powyższego kodu w porównaniu z 481 dla zwykłegostd::min
.źródło
for(:)
wi integrując z cofniętym obiektem. Poprawka: ideone.com/tQVOalstd::move()
jest używany tylko jako wyraźna obsada, aby lepiej zilustrować ten punkt. To nie jest kod, który można skopiować i wkleić do projektu. Nie jest to sprzeczne z odpowiedzią z najwyższą liczbą głosów, ponieważ wewnątrz funkcji tworzony jest obiekt tymczasowy. Tutaj zwrócony obiekt jest jednym z argumentów (obiekty tymczasowe są niszczone jako ostatni krok w ocenie pełnego wyrażenia, które (leksykalnie) zawiera punkt, w którym zostały utworzone).