Как typedef возвращаемый тип метода из класса шаблона?
У меня есть шаблонный класс Helper
, который выглядит следующим образом:
template< typename Mapper >
class Helper
{
public:
using mappedType = ... ;
};
Мне понадобится mappedType
для типа, возвращаемого методом map(const int&)
в классе Mapper
. Для допустимого типа для Mapper
, как показано ниже:
class DMapper
{
public:
double map(const int& val){ ... }
};
Helper<DMapper>::mappedType
должен быть double
. Есть ли способ сделать это без создания экземпляра Mapper
?
Ближайший я получил:
using mappedType = typename std::result_of<
decltype(&Mapper::map)(Mapper const*, const int&)
>::type;
Но type
в этом случае не определяется.
EDIT:
Если я могу избежать использования фиктивного аргумента для int
, это было бы еще лучше (в моем конкретном коде аргумент не так прост).
Ответы
Ответ 1
Ближе всего я получил
using mappedType = typename std::result_of<decltype(&Mapper::map)(Mapper const*, const int&)>::type;
Вы почти получили его.
Автоматически объявленный указатель this
не является константой в методах непостоянного класса, поэтому ваш
decltype(&Mapper::map)(Mapper const*, const int&)
не соответствует методу в классе Mapper
. Удалите квалификатор const
из первого аргумента, и ваше решение result_of
будет работать без аргументов instance и dummy:
using mappedType = typename std::result_of<
decltype(&Mapper::map)(Mapper /*no const here*/ *, const int&)
>::type;
Ответ 2
Вы можете использовать std::declval
для использования функций-членов в decltype
без создания экземпляра:
using mappedType = decltype(std::declval<Mapper>().map(0));
std::declval
также может использоваться для аргументов:
using mappedType = decltype(std::declval<Mapper>().map(std::declval<int>()));
Ответ 3
Предполагая, что Mapper::map
не является перегруженным методом, его тип возврата может быть разрешен автоматически следующим образом:
template< typename Mapper >
class Helper
{
private:
template<class R, class... T>
static R resolveReturnType(R (Mapper::*)(T...));
template<class R, class... T>
static R resolveReturnType(R (Mapper::*)(T...) const);
public:
using mappedType = decltype(resolveReturnType(&Mapper::map));
};