Удалить ссылку в decltype (вернуть T вместо T &, где T & - это decltype)

(Если вы профессионал в C ++ 11, перейдите к жирному абзацу.)

Допустим, я хочу написать шаблонный метод, который вызывает и возвращает результат переданного объекта, тип которого является параметром шаблона:

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

ТакT должен иметь методReturnType T::bar() const для того, чтобы использоваться в вызове, как это:

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

Нам не нужно писатьMyClass благодаря выводу типа и вызов становится:

int x = doSomething<int>(object);

Но опуская<int> тоже приводит к ошибке компиляции, потому что метод не требует возврата int для назначенияx потом (может вернутьсяchar например).

В C ++ 0x / 11 мы имеемauto а такжеdecltype с помощью которого мы можем использовать тип вывода метода шаблона:

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

Компилятор теперь выяснит, какой типfoo.bar() это и просто использует это как тип возвращаемого значения. С нашим конкретным классомMyClass это будетint и следующего будет достаточно:

int x = doSomething(object);

Теперь на мой вопрос:

Если MyClass определяетbar() как возвращениеint&тип возвратаdoSomething(object) также будетint& = decltype(foo.bar()), Это проблема, так как теперь G ++ соответствует тому, что явозврат ссылки на временный.

Как я могу это исправить? Есть ли что-то вродеremove_reference который можно использовать какremove_reference(decltype(foo.bar()))?

Я думал о том, чтобы просто объявить вспомогательный метод, который принимаетT& и возвращаетT а затем определить тип возвращаемого значенияdoSomething бытьdecltype(helper(foo.bar())), Но должен быть лучший способ, я чувствую это.

Ответы на вопрос(1)

Ваш ответ на вопрос