Czy zwracanie przez rvalue reference jest bardziej efektywne?
Na przykład:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
2 answers
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Zwraca zwisające odniesienie, podobnie jak w przypadku przypadku odniesienia lvalue. 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 obiekt Beta_ab
do wartości zwracanej funkcji. Jeśli kompilator może, całkowicie uniknie tego ruchu, używając RVO (return value optimization). Teraz możesz wykonać następujące czynności
Beta_ab ab = others.toAB();
And it will move należy utworzyć tymczasowe w ab
, lub zrobić RVO, aby całkowicie pominąć wykonywanie ruchu lub kopiowania. Polecam przeczytać Boostcon09 rvalue referuje 101, który wyjaśnia sprawę i jak (N)RVO oddziałuje z tym.
Twój przypadek zwrócenia referencji rvalue byłby dobrym pomysłem przy innych okazjach. Wyobraź sobie, że masz getAB()
funkcję, którą często wywołujesz na tymczasowej. Nie jest optymalne, aby zwracało odniesienie const lvalue dla rvalue temporary. Możesz zaimplementuj to 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 opcjonalne, ponieważ ab
nie jest ani lokalną automatyczną, ani tymczasową wartością r. ref-kwalifikator &&
mówi, że druga funkcja jest wywoływana na rvalue temporary, wykonując następujący ruch, zamiast copy
Beta_ab ab = Beta().getAB();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-12 20:28:10
To Może być bardziej efektywne, 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;
}
Jako ciekawostkę, na mojej maszynie clang++ -O3
generuje 54 instrukcje dla kodu powyżej w porównaniu do 62 instrukcji dla zwykłego std::min
. Jednak z -O0
generuje 518 instrukcji dla kodu powyżej, a 481 dla zwykłego std::min
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 17:15:09