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.

questionAnswers(1)

yourAnswerToTheQuestion