c++ c++11 rvalue-reference

c++ - ¿La devolución por referencia de valor es más eficiente?



c++11 rvalue-reference (2)

por ejemplo:

Beta_ab&& Beta::toAB() const { return move(Beta_ab(1, 1)); }


Puede ser más eficiente, por ejemplo, en un contexto un poco diferente:

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; }

Como observación interesante, en mi máquina clang++ -O3 genera 54 instrucciones para el código anterior frente a 62 instrucciones para el std::min . Sin embargo, con -O0 genera 518 instrucciones para el código anterior frente a 481 para el -O0 std::min .


Beta_ab&& Beta::toAB() const { return move(Beta_ab(1, 1)); }

Esto devuelve una referencia colgante, al igual que con el caso de referencia lvalue. Después de que la función retorna, el objeto temporal será destruido. Debería devolver Beta_ab por valor, como el siguiente

Beta_ab Beta::toAB() const { return Beta_ab(1, 1); }

Ahora, está moviendo correctamente un objeto Beta_ab temporal en el valor de retorno de la función. Si el compilador puede, evitará el movimiento por completo, mediante el uso de RVO (optimización del valor de retorno). Ahora, puedes hacer lo siguiente

Beta_ab ab = others.toAB();

Y moverá construir el temporal en ab , o hacer RVO para omitir hacer un movimiento o copiar por completo. Le recomiendo que lea BoostCon09 Rvalue References 101 que explica el asunto y cómo (N) RVO interactúa con esto.

Su caso de devolver una referencia de valor sería una buena idea en otras ocasiones. Imagine que tiene una función getAB() que a menudo invoca temporalmente. No es óptimo hacer que devuelva una referencia de const lvalue para valores temporales rvalue. Puedes implementarlo así

struct Beta { Beta_ab ab; Beta_ab const& getAB() const& { return ab; } Beta_ab && getAB() && { return move(ab); } };

Tenga en cuenta que move en este caso no es opcional, porque ab no es un valor local automático ni un valor r temporal. Ahora, el calificador de ref && dice que la segunda función se invoca en rvalue temporales, haciendo el siguiente movimiento, en lugar de copiar

Beta_ab ab = Beta().getAB();