Elimine la referencia en decltype (devuelva T en lugar de T y donde T & es el decltype)
(Si eres un profesional de C ++ 11, salta al párrafo en negrita.)
Digamos que quiero escribir un método de plantilla que llame y devuelva el resultado de un objeto pasado cuyo tipo es el parámetro de plantilla:
template<ReturnType, T>
ReturnType doSomething(const T & foo) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
Asi queT
tiene que tener un métodoReturnType T::bar() const
para ser utilizado en una llamada como esta:
struct MyClass {
...
int bar() const;
...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);
No tenemos que escribirMyClass
Gracias al tipo deducción y la llamada se convierte en:
int x = doSomething<int>(object);
Pero omitiendo<int>
también resulta en un error de compilación porque el método no requiere devolver int para ser asignado ax
despues (podria volverchar
por ejemplo).
En C ++ 0x / 11 tenemos elauto
ydecltype
con el que podemos usar para deducir el tipo de retorno de un método de plantilla:
template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
El compilador ahora descubrirá cual es el tipo defoo.bar()
es y solo usa esto como el tipo de retorno. Con nuestra clase concretaMyClass
este será unint
y lo siguiente sería suficiente:
int x = doSomething(object);
Ahora a mi pregunta:
Si MyClass definebar()
como devolver unint&
, el tipo de retorno dedoSomething(object)
también será unint&
= decltype(foo.bar())
. Esto es un problema, ya que como G ++ ahora cumple, estoyregresando la referencia a temporal.
¿Cómo puedo arreglar esto? Hay algo comoremove_reference
que se puede utilizar comoremove_reference(decltype(foo.bar()))
?
Pensé en declarar un método de ayuda que toma unaT&
y devuelve unT
y luego definir el tipo de retorno dedoSomething
serdecltype(helper(foo.bar()))
. Pero tiene que haber una mejor manera, lo estoy sintiendo.