I have a templated class Helper
which looks like this:
template< typename Mapper >
class Helper
{
public:
using mappedType = ... ;
};
I would need mappedType
to be the type returned by the map(const int&)
method in the Mapper
class. Given a valid type for Mapper
like the following:
class DMapper
{
public:
double map(const int& val){ ... }
};
Helper<DMapper>::mappedType
should be double
. Is there a way to do that without instantiating a Mapper
?
The closest I got is:
using mappedType = typename std::result_of<
decltype(&Mapper::map)(Mapper const*, const int&)
>::type;
But type
is not defined in this case.
EDIT:
If I can avoid using a dummy argument for the int
, that would be even better (in my concrete code, the argument is not that simple).
Absolutely, this is possible. This is also quite common - for example, Factory Method pattern can be implemented within a single class, in which case member functions would be returning instances of the class of which they are members.
Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
You can use std::declval
to use member functions in decltype
without creating an instance:
using mappedType = decltype(std::declval<Mapper>().map(0));
std::declval
can be used for arguments as well:
using mappedType = decltype(std::declval<Mapper>().map(std::declval<int>()));
The closest I got is
using mappedType = typename std::result_of<decltype(&Mapper::map)(Mapper const*, const int&)>::type;
You almost got it.
Auto-declared this
pointer is not constant in non-constant class methods, so your
decltype(&Mapper::map)(Mapper const*, const int&)
does not match any method in Mapper
class. Remove const
qualifier from the first argument, and your result_of
solution will work without instancing and dummy arguments:
using mappedType = typename std::result_of<
decltype(&Mapper::map)(Mapper /*no const here*/ *, const int&)
>::type;
Assuming that Mapper::map
is not an overloaded method, its return type can be resolved automatically as follows:
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));
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With