Удалить ссылку в 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()))
, Но должен быть лучший способ, я чувствую это.