How to extract lambda's Return Type and Variadic Parameters Pack back from general template
我想创建一个接收lambda的模板化类或函数,并将其内部放入std :: function <>
Lambda可以具有任意数量的输入参数[](int a,float b,...)std :: function <>应对应于lambda的operator()的类型
1 2 3 4 5 6 7 8 9 10 11 | template <typename T> void getLambda(T t) { // typedef lambda_traits::ret_type RetType; ?? // typedef lambda_traits::param_tuple --> somehow back to parameter pack Args... std::function<RetType(Args...)> fun(t); } int main() { int x = 0; getLambda([&x](int a, float b, Person c){}); } |
所以我需要以某种方式提取返回类型和参数包
这里的答案建议对lambda的:: operator()使用部分规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | template <typename T> struct function_traits : public function_traits<decltype(&T::operator())> {}; template <typename ClassType, typename ReturnType, typename... Args> struct function_traits<ReturnType(ClassType::*)(Args...) const> // we specialize for pointers to member function { enum { arity = sizeof...(Args) }; // arity is the number of arguments. typedef ReturnType result_type; template <size_t i> struct arg { typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; // the i-th argument is equivalent to the i-th tuple element of a tuple // composed of those arguments. }; }; |
但是我需要一种将tuple <>转换回参数包的方法,以创建适当的std :: function <>实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | template <typename T> struct function_traits : public function_traits<decltype(&T::operator())> {}; template <typename ClassType, typename ReturnType, typename... Args> struct function_traits<ReturnType(ClassType::*)(Args...) const> // we specialize for pointers to member function { using result_type = ReturnType; using arg_tuple = std::tuple<Args...>; static constexpr auto arity = sizeof...(Args); }; template <class F, std::size_t ... Is, class T> auto lambda_to_func_impl(F f, std::index_sequence<Is...>, T) { return std::function<typename T::result_type(std::tuple_element_t<Is, typename T::arg_tuple>...)>(f); } template <class F> auto lambda_to_func(F f) { using traits = function_traits<F>; return lambda_to_func_impl(f, std::make_index_sequence<traits::arity>{}, traits{}); } |
上面的代码应做您想要的。 如您所见,主要思想是创建一个整数包。 这是等距变量的非类型模板等效项。 我不知道可以使用这种包而不调用另一个函数的任何技术,因此通常在使用元组的情况下,您会看到一个嵌套的" impl"函数可以完成所有工作。 一旦有了整数包,就可以在访问元组时将其展开(也可以获取值)。
需要注意的是:使用