Remova a referência em decltype (retorne T em vez de T & onde T & é o declype)
(Se você é um profissional de C ++ 11, pule para o parágrafo em negrito).
Digamos que eu queira escrever um método de modelo que chame e retorne o resultado de um objeto passado, cujo tipo é o parâmetro do modelo:
template<ReturnType, T>
ReturnType doSomething(const T & foo) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
assimT
tem que ter um métodoReturnType T::bar() const
para ser usado em uma chamada como esta:
struct MyClass {
...
int bar() const;
...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);
Nós não temos que escreverMyClass
graças ao tipo de dedução e a chamada se torna:
int x = doSomething<int>(object);
Mas omitindo<int>
também resulta em um erro de compilação porque o método não precisa retornar int para ser atribuído ax
depois (poderia retornarchar
por exemplo).
Em C ++ 0x / 11, temos oauto
edecltype
com o qual podemos usar para deduzir o tipo de retorno de um método de modelo:
template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
O compilador agora descobrirá qual é o tipo defoo.bar()
é e apenas usa isso como o tipo de retorno. Com a nossa classe concretaMyClass
esta será umaint
e o seguinte seria suficiente:
int x = doSomething(object);
Agora a minha pergunta:
Se MyClass definebar()
como retornar umint&
, o tipo de retornodoSomething(object)
também será umint&
= decltype(foo.bar())
. Isso é um problema, já que como o G ++ agora cumpre que eu souretornando referência a temporária.
Como posso consertar isso? Existe algo comoremove_reference
que pode ser usado comoremove_reference(decltype(foo.bar()))
?
Eu pensei em apenas declarar um método auxiliar que leva umT&
e retorna umT
e depois definir o tipo de retornodoSomething
ser estardecltype(helper(foo.bar()))
. Mas tem que haver uma maneira melhor, estou sentindo isso.