función de plantilla y boost::remove_reference
Frecuentes
Visto 706 veces
1
Estoy rastreando un error del compilador de C++ que no puedo descifrar. Lo he reducido a este código:
#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
template<typename T> inline const T bar( T in )
{
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type nonref;
const nonref* inPtr = ∈
return *inPtr;
}
class Foo
{
};
int main()
{
Foo foo;
const Foo& ref = bar< Foo& >( foo );
}
lo que resulta en:
tt.cpp: In function ‘const T bar(T) [with T = Foo&]’:
tt.cpp:19:39: instantiated from here
tt.cpp:9:13: error: invalid initialization of reference of type ‘Foo&’ from expression of type ‘const nonref {aka const Foo}’
¿Cuál es el problema real aquí? ¿Por qué falta la const en el valor de retorno? Necesito remove_reference ya que el código real lo requiere.
3 Respuestas
3
La aplicación de const
a un tipo de referencia no hace nada. Necesitas hacer el argumento de la plantilla. const foo &
, o elimine la referencia y luego vuelva a agregar ambos const
y la referencia en la propia firma de la función.
Vea también ¿Cuándo debo usar remove_reference y add_reference? particularmente el segundo párrafo.
contestado el 23 de mayo de 17 a las 13:05
1
Usando VisualStudio 2008 me sale el siguiente error
error C2440: 'return' : cannot convert from 'const nonref' to 'Foo &'
Cambio de bate a
template<typename T> inline const typename boost::remove_reference<T>::type& bar( T in )
{
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type nonref;
const nonref* inPtr = ∈
return *inPtr;
}
corrige esto y el código compila.
contestado el 22 de mayo de 12 a las 15:05
0
Volviendo const T
de su función no hace lo que espera. Por tu código entiendo que esperas que regrese const Foo&
, cual es una referencia a un objeto inmutable de tipo Foo
.
Pero cuando T
is Foo&
, la expresion const T
significa una referencia inmutable a un objeto de tipo Foo
. Dado que las referencias son siempre inmutables, ¡la parte const simplemente se elimina (de acuerdo con el párrafo 8.3.2 de la especificación)! Es decir, su función devuelve Foo&
y no const Foo&
y eso es lo que el compilador intenta decirte.
contestado el 22 de mayo de 12 a las 15:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c++ boost or haz tu propia pregunta.
Pero, sutilmente, el tipo de retorno de la función aún no es
const
, que probablemente no es lo que ella pretende. - PatataswatterPues… ahora vuelve por valor, no por referencia. Quizás casualmente este es otro contexto donde
const
se ignora Personalmente me replantearía un diseño que requieraconst
para ser añadido debajo de una referencia. - Patataswatter