I would like to create a wrapper class of a std::function (WrapperFunction) that doesn't need templates to be built. So, I'm wandering if it is possible to create a std::function and decompose it in its return type, arguments and function (lambda) and passing them to the constructor of WrapperFunction. The main task of WrapperFunction class would be to store these three data and return them in a proper way (for example through three getters). The will is to instantiate and pass around this class to not propagate templates needed to make a std::function.
A not working pseudo-code example to show the idea could be:
auto f = std::function<bool(int, int)>([](int a, int b){ return a == b;});
ReturnType rt = f.give_me_return_type;
Arguments args = f.give_me_args;
Lambda lambda = f.five_me_lambda;
auto functionWrapper = FunctionWrapper(rt, args, lambda);
auto result = std::function<functionWrapper.getReturnType()(functionWrapper.getArguments())>(functionWrapper.getLambda());
Is possible to do that? or does exist something similar?
Is possible to do that? or does exist something similar?
Short answer: no.
Long answer.
You ask to decompose a std::function
initialized with a lambda in three components
The point (1) is simple to obtain. Not in the form of a rt
variable
ReturnType rt = f.give_me_return_type;
but in the form of a using
type alias
using ReturnType = typename decltype(f)::result_type;
The point (2) is more because there isn't possible make a using
alias for a variadic list of types; the best I can imagine is to wrap the variadic list in a template-template container; std::tuple
is the first that come in my mind.
The best I can imagine is the develop of a type traits
template <typename>
struct funcArgTupler;
template <typename R, typename ... Args>
struct funcArgTupler<std::function<R(Args...)>>
{ using type = std::tuple<Args...>; };
and use it as follows
using ArgTuple = typename funcArgTupler<decltype(f)>::type;
The point (3), in general, is impossible because std::function
can be initialized not only with lambda but also simple function pointers, struct/class methods and static struct/class methods.
The type std::function
give you a template method, target()
, that return a pointer to the stored callable; the problem is that you have to know the type of the stored callable. And the type of a lambda is unique, so you have to register it somehow.
The best I can imagine is register the original lambda in a variable
auto l1 = [](int a, int b){ std::cout << "l1" << std::endl;
return a == b;};
auto f = std::function<bool(int, int)>(l1);
and get it
auto l2 = f.target<decltype(l1)>();
if ( l2 )
(*l2)(1, 2); // print l1
Said this, I don't know if make sense create a FunctionWrapper
as you ask.