Usuń odwołanie w decltype (zwróć T zamiast T i gdzie T i jest decltype)
(Jeśli jesteś C ++ 11 pro, przejdź do pogrubionego akapitu).
Powiedzmy, że chcę napisać metodę szablonu, która wywołuje i zwraca wynik przekazanego obiektu, którego typ jest parametrem szablonu:
template<ReturnType, T>
ReturnType doSomething(const T & foo) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
WięcT
musi mieć metodęReturnType T::bar() const
w celu wykorzystania w takim połączeniu:
struct MyClass {
...
int bar() const;
...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);
Nie musimy pisaćMyClass
dzięki odliczeniu typu i rozmowa staje się:
int x = doSomething<int>(object);
Ale pomijając<int>
powoduje również błąd kompilacji, ponieważ metoda nie wymaga zwracania int, aby można go było przypisaćx
potem (może wrócićchar
na przykład).
W C ++ 0x / 11 mamyauto
idecltype
za pomocą których możemy wywnioskować typ powrotu metody szablonu:
template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
Kompilator dowie się teraz, jakiego rodzajufoo.bar()
jest i używa tego jako typu powrotu. Z naszą betonową klasąMyClass
to będzieint
a wystarczy:
int x = doSomething(object);
Teraz do mojego pytania:
Jeśli MyClass definiujebar()
jako zwrotint&
, typ powrotudoSomething(object)
będzie takżeint&
= decltype(foo.bar())
. To jest problem, ponieważ G ++ jest teraz zgodny z tym, że jestemzwracając odwołanie do tymczasowego.
Jak mogę to naprawić? Czy jest coś takiegoremove_reference
które mogą być używane jakremove_reference(decltype(foo.bar()))
?
Myślałem o zadeklarowaniu metody pomocniczej, która pobieraT&
i zwraca aT
a następnie zdefiniuj typ powrotudoSomething
byćdecltype(helper(foo.bar()))
. Ale musi być lepszy sposób, czuję to.