Получить тип возврата функции-члена без объекта - PullRequest
37 голосов
/ 07 апреля 2011

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

Другими словами, я бы хотел шаблон класса

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

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

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

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

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

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

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

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

Ответы [ 2 ]

58 голосов
/ 07 апреля 2011

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

decltype(((T*)nullptr)->foo()) footype;
39 голосов
/ 07 апреля 2011

Другая альтернатива:

#include <utility>

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

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

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

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

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

...