La semántica de movimiento puede ser útil cuando el compilador no puede usar RVO y NRVO. ¿Pero en qué caso el compilador no puede usar estas características?¿Cuándo un compilador no puede usar RVO o NRVO?
Respuesta
La respuesta es que depende del compilador y de la situación. P.ej. la ramificación del flujo de control puede confundir a los optimizadores. Wikipedia dar este ejemplo:
#include <string>
std::string f(bool cond = false) {
std::string first("first");
std::string second("second");
// the function may return one of two named objects
// depending on its argument. RVO might not be applied
return cond ? first : second;
}
int main() {
std::string result = f();
}
Bueno, no se trata tanto de si el compilador puede usar RVO, sino de si puede evitar la construcción de una copia.
considerar:
struct Blah
{
int x;
Blah(int const _x): x(_x) { cout << "Hum de dum " << x << endl; }
};
Blah foo()
{
Blah const a(1);
if(fermatWasRight()) { return Blah(2); }
return a;
}
Obtención de los efectos secundarios (salida desde el constructor) aquí, es a primera vista bastante incompatible con la construcción de a
o directamente en el almacenamiento proporcionado por la persona que llama. Pero si el compilador es lo suficientemente inteligente, puede notar que la destrucción de este objeto es una operación nula. Y, en términos más generales, para cualquier situación en particular, si el compilador es lo suficientemente inteligente, tal vez pueda evitar una operación de copia, sin importar qué tan furtivamente diseñemos el código.
No estoy seguro de lo formal, pero lo anterior, con más carga en el objeto para que la copia sea más costosa, es un caso donde la semántica de movimiento puede ayudar, de modo que la optimización estará garantizada sin importar el inteligencia del compilador (o no).
- 1. RVO/NRVO y el constructor público de copia no definida
- 2. ¿Se copia el objeto o no cuando se inicia RVO/NRVO?
- 3. ¿Cuándo debería iniciarse RVO?
- 4. Cuándo usar (o no usar) un delegado
- 5. Sincronización, ¿Cuándo o no usar?
- 6. ¿Cuándo un compilador puede inferir un parámetro de plantilla?
- 7. Cuándo usar Restringir y cuándo no a
- 8. ¿Por qué no se permite RVO al devolver un parámetro?
- 9. Cuándo usar InvalidOperationException o NotSupportedException?
- 10. ¿Puede alguien explicarme cuándo es útil usar MapMaker o WeakHashMaps?
- 11. ¿Cuándo sabe cuándo usar TreeSet o LinkedList?
- 12. Cuándo usar interfaces o clases abstractas? Cuándo usar ambos?
- 13. ¿Cuándo no usar ACS?
- 14. RVO, mover operaciones y un dilema
- 15. Cuándo usar strncpy o memmove?
- 16. Diseño web: cuándo (no) usar un asistente
- 17. Cuándo usar y cuándo no usar Try Catch Finally
- 18. Cuándo usar OSGi EventAdmin y cuándo no?
- 19. ¿Cuándo obtuvo Java un compilador JIT?
- 20. cuándo deberíamos usar instanceof y cuándo no
- 21. Cuándo usar GWT y cuándo no
- 22. Cuándo usar un árbol de sintaxis abstracto o concreto?
- 23. Para usar o no usar expresiones regulares?
- 24. Cuándo usar, no usar, OneToOne y ManyToOne
- 25. Tipos incorporados, cuándo (no) usar?
- 26. Cuándo usar os.name, sys.platform o platform.system?
- 27. ¿Puede darme un ejemplo de cuándo debería usar UIElement.UpdateLayout()?
- 28. ¿Cuándo debería usar un analizador?
- 29. Cuándo usar un módulo y cuándo usar una clase
- 30. ¿Cuándo * no * usar declaraciones preparadas?
Comprobar esta pregunta: [C++: Evitar la copia con la afirmación “retorno”] (http://stackoverflow.com/questions/10476665/c-avoiding-copy-with-the- return-statement) :) – LihO