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.