2012-02-05 14 views
21

¿Qué ventajas tiene usar std::reference_wrapper como parámetro de plantilla de contenedores en lugar de punteros sin formato? Es decir std::vector<std::reference_wrapper<MyClass> > vs std::vector<MyClass*>¿Beneficios de usar reference_wrapper en lugar de puntero sin formato en contenedores?

me gusta olvidarse de los nulos y no tener que utilizar la sintaxis de puntero, pero el nivel de detalle de los tipos (es decir vector<reference_wrapper<MyClass> >), además de tener la llamada std :: ref lugar de uso para envolver la referencia real me hace piensa que no vale la pena.

Me refiero a casos en los que usar std :: shared_ptr o cualquier otro puntero inteligente no es una opción.

¿Hay otros beneficios de usar reference_wrapper o cualquier otro factor que actualmente no estoy teniendo en cuenta? (Creo que mi pregunta se aplica tanto a la referencia_wrapper de C++ 11 como a la de refuerzo)

+5

IMO, la no invalidación de referencia es una gran ventaja, que a menudo supera la verbosidad. Pero esta es solo una opinión de un odiado nulo experimentado. – kkm

+0

@kkm mantiene este argumento con [not_null] (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i12-declare-a-pointer-that-must-not-be-null -as-not_null) punteros? – Woofas

+0

@Woofas: Tal vez no. No estoy muy familiarizado con las últimas propuestas de idiomas. ¡Este ha estado fuera durante tres días! :) – kkm

Respuesta

18

No creo que haya ninguna diferencia técnica. El contenedor de referencia proporciona funcionalidad básica de puntero, incluida la capacidad de cambiar el destino de forma dinámica.

Una de las ventajas es que demuestra la intención. Les dice a las personas que leen el código que "quien quiera" tiene la variable, en realidad no está controlando su vida útil. El usuario no olvidó borrar o nada nuevo, que algunas personas pueden comenzar a buscar cuando ven la semántica del puntero.

+1

Corolario: las referencias/ref_wrappers no previenen los problemas de duración del objeto, aunque su sintaxis es mejor que la de los punteros. – mskfisher

+0

Sí, de hecho se trata de intento. Yo agregaría que las referencias son punteros no nulos. 'std :: vector ' podría tener un nullptr, mientras que al iterar sobre un vector de referencias, sabrá que todos ellos son válidos. –

0

Las referencias C son realmente problemáticas cuando se trabaja con plantillas. Si usted es "suerte" de compilar el código con referencia como parámetro de plantilla que podría tener problemas con el código que trabajarían (por alguna razón) de la siguiente manera:

template<class T> f(T x) { g(x); } 
template<class T> g(T x) { x++; } 

Entonces, incluso si se llama f<int&>(x) se llamará g<int> . Pero reference_wrapper funciona bien con plantillas.

Como también se mencionó anteriormente, tendrá problemas para compilar cosas como vector<int&>, pero vector<reference_wrapper<int>> funciona bien.

+0

"Entonces, incluso si llama a' f (x) 'llamará a' g '." Sí, creo que esto se debe a que no tomaste el argumento a 'f()' como una referencia de reenvío y luego 'std :: forward' it a' g() '. Creo que si lo hicieras, podrías hacer que esto funcione. Si es así, perder un paso al codificar no hace que el lenguaje sea "realmente problemático". ;-) –

Cuestiones relacionadas