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

Как 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, это было бы еще лучше (в моем конкретном коде аргумент не так прост).

4b9b3361

Ответ 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));
};