C + + can obtain the required parameter types according to the function pointer passed in, and then obtain the required parameters according to the parameter source. Here I use tuple as a demonstration. However, as long as the actual parameters can be obtained according to the sequence number or order, similar methods can be used:
First, an auxiliary function is given:
/* * Get nth type */ template <typename... Cases> struct select { }; template <typename T, typename... Cases> struct select<T, Cases...> : public select<Cases...> { using ThisType = T; using Base = select<Cases...>; };
The following is the actual implementation function:
#include <functional> #include "vs-help.h" class TupleFunc { public: TupleFunc() { } // The actual construction process of function template <typename Ret, typename... Args, typename ParamsSource> void makeFuncAndParams(Ret(*func)(Args...), ParamsSource& paramSource) { makeFuncAndParamsImpl<0>(func, select<Args...>(), paramSource); } // Actual call void invoke() { m_func(); } private: // Actual call initialization template <size_t idx, typename Func, typename Select, typename ParamsSource, typename... Params> void makeFuncAndParamsImpl(Func&& func, Select, ParamsSource& paramSource, Params&&...args) { typename Select::ThisType param = std::get<idx>(paramSource); makeFuncAndParamsImpl<idx + 1>(func, Select::Base(), paramSource, std::forward<Params>(args)..., std::move(param)); } // End call template <size_t idx, typename Func, typename ParamSource, typename... Params> void makeFuncAndParamsImpl(Func&& func, select<>, ParamSource& paramSource, Params&&... args) { m_func = [func, args...]() { func(args...); }; } private: std::function<void()> m_func; };
Here are the test cases:
void print(int x, std::string y) { std::cout << "x: " << x << std::endl; std::cout << "y: " << y << std::endl; } int main() { std::tuple<int, std::string, std::string> p = { 12, "job", "China" }; TupleFunc func; func.makeFuncAndParams(&print, p); func.invoke(); return 0; }
Through the use of lambda expression, we can easily build a function we need when we call, and the existence of templates can make us dynamic when building a lambda expression, so that in some cases, we can more flexibly build various processing functions map, etc. The above is just a simple demonstration. In specific scenarios, some modifications are needed.