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.

questionAnswers(1)

yourAnswerToTheQuestion