Referenz in decltype entfernen (T anstelle von T & zurückgeben, wobei T & der decltype ist)

(Wenn Sie ein C ++ 11-Profi sind, fahren Sie mit dem fett gedruckten Abschnitt fort.)

Angenommen, ich möchte eine Template-Methode schreiben, die das Ergebnis eines übergebenen Objekts aufruft und zurückgibt, dessen Typ der Template-Parameter ist:

template<ReturnType, T>
ReturnType doSomething(const T & foo) {
    return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}

SoT muss eine Methode habenReturnType T::bar() const Um in einem Anruf wie diesem verwendet zu werden:

struct MyClass {
    ...
    int bar() const;
    ...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);

Wir müssen nicht schreibenMyClass dank typenabzug und der aufruf wird:

int x = doSomething<int>(object);

Aber weglassen<int> Auch dies führt zu einem Kompilierungsfehler, da die Methode nicht int zurückgeben muss, um zugewiesen zu werdenx danach (es könnte zurückkehrenchar zum Beispiel).

In C ++ 0x / 11 haben wir dieauto unddecltype womit wir den Rückgabetyp einer Template-Methode ableiten können:

template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
    return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}

Der Compiler wird nun herausfinden, welche Art vonfoo.bar() ist und verwendet dies nur als Rückgabetyp. Mit unserer konkreten KlasseMyClass das wird einint und folgendes würde genügen:

int x = doSomething(object);

Nun zu meiner Frage:

Wenn MyClass definiertbar() als Rücksendungint&, der Rückgabetyp vondoSomething(object) wird auch einint& = decltype(foo.bar()). Dies ist ein Problem, da G ++ jetzt das erfüllt, was ich binRückverweis auf temporär.

Wie kann ich das beheben? Gibt es so etwas wieremove_reference die kann gerne verwendet werdenremove_reference(decltype(foo.bar()))?

Ich habe darüber nachgedacht, einfach eine Hilfsmethode zu deklarieren, die a benötigtT& und gibt a zurückT und definieren Sie dann den Rückgabetyp vondoSomething seindecltype(helper(foo.bar())). Aber es muss einen besseren Weg geben, ich fühle es.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage