Подтвердить что ты не робот

Получить возвращаемый тип функции-члена без объекта

У меня есть несколько классов, которые я не могу изменить. Каждый из них имеет конструктор копирования, по крайней мере один другой конструктор и функцию foo(), которая возвращает некоторое значение. Я хочу создать шаблон класса, который может быть получен из каждого из этих классов, и имеет член данных, который является тем же типом, что и тип возврата foo() (извините, если у меня есть некоторая терминология).

Другими словами, мне нужен шаблон класса

template<typename T> class C : public T
{
  footype fooresult;
};

где footype - тип возврата T::foo().

Если базовые классы имели, скажем, конструктор по умолчанию, я мог бы сделать

decltype(T().foo()) fooresult;

(с функциональностью С++ 0x в GCC), но классы не имеют никакого конкретного конструктора, кроме конструкторов копирования.

GCC также не позволяет decltype(this->foo()), хотя, по-видимому, есть вероятность, что это будет добавлено к стандарту С++ 0x - знает ли кто-нибудь, насколько это возможно?

Мне кажется, что возможно сделать что-то по строкам decltype(foo()) или decltype(T::foo()), но они, похоже, не работают: GCC дает ошибку формы cannot call member function 'int A::foo()' without object.

Конечно, у меня может быть дополнительный параметр шаблона footype или даже неклассовый параметр типа T, но есть ли способ избежать этого?

4b9b3361

Ответ 1

Вам это не нужно: помните, что поскольку decltype не оценивает его аргумент, вы можете просто вызвать nullptr.

decltype(((T*)nullptr)->foo()) footype;

Ответ 2

Другой вариант:

#include <utility>

template<typename T> class C : public T
{
   decltype(std::declval<T>().foo()) footype;
};

declval возвращает a T&&. Или, если foo может быть перегружен квалификаторами rvalue-ref, и вы хотите, чтобы вы получили перегрузку lvalue foo:

   decltype(std::declval<T&>().foo()) footype;

В этом примере declval возвращает a T&.

Как и решение ((T*)nullptr)->, std::declval не предъявляет требований к типу T.