por ejemplo:¿Es la devolución por referencia de valor más eficiente?
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
por ejemplo:¿Es la devolución por referencia de valor más eficiente?
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Esto devuelve una referencia colgando, igual que con el caso de referencia lvalue. Después de que la función retorna, el objeto temporal será destruido. Debe devolver Beta_ab
por valor, como la siguiente
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Ahora, se está moviendo adecuadamente un Beta_ab
objeto 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, usted puede hacer lo siguiente
Beta_ab ab = others.toAB();
y se moverá construir el temporal en ab
, o hacer RVO omitir haciendo 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 rvalue 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. Es posible implementar como este
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 no es ni un ab
automática local ni un rvalue temporal. Ahora, el ref-calificador&&
dice que la segunda función se invoca en los temporales rvalue, por lo que el siguiente movimiento, en lugar de la copia
Beta_ab ab = Beta().getAB();
Siempre había asumido el problema de referencia que cuelga se fue automágicamente cuando el tipo de retorno era una referencia de valor r. Me alegro de haberlo descifrado antes de que me mordiera. Los insectos aplastantes apilan. –
:) Realmente, las referencias rvalue son "solo referencias" como las referencias lvalue. no copian ni almacenan nada. –
E incluso si no elimina a los constructores, el compilador sabe que puede devolver un rvalue-ref automáticamente de forma segura. Por ejemplo, de acuerdo con mis experimentos, 'return x;' es lo mismo que 'return std :: move (x)'. (donde 'x' es una variable local (es decir, este punto que he hecho no se aplica directamente a la pregunta original sobre la devolución de un temporal)). –