简体   繁体   English

如何从通用模板<typename T>中提取lambda的Return Type和Variadic Parameters Pack

[英]How to extract lambda's Return Type and Variadic Parameters Pack back from general template<typename T>

I want to create a templated class or function, that receives a lambda, and puts it internally in std::function<> Lambda could have any number of input parameters [](int a, float b, ...) std::function<> should correspond to the lambda's operator()'s type 我想创建一个模板化的类或函数,它接收一个lambda,并将它放在std :: function <>内部.Lambda可以有任意数量的输入参数[](int a,float b,...)std :: function <>应该对应lambda的operator()的类型

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){}); 
}

So I need to somehow extract the Return Type and Parameter Pack 所以我需要以某种方式提取返回类型和参数包

Answer here suggests to use partial spec on lambda's :: operator() 这里的答案建议在lambda的:: operator()上使用部分规范

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.
    };
};

But I need a way to convert tuple<> back to parameters pack, to create a proper std::function<> instantiation 但我需要一种方法将元组<>转换回参数包,以创建一个正确的std :: function <>实例化

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{});
}

The code above should do what you want. 上面的代码应该做你想要的。 The main idea, as you can see, is to create an integer pack. 如您所见,主要思想是创建一个整数包。 This is the non-type template equivalent of variadics. 这是variadics的非类型模板。 I don't know of any technique by which you can use such a pack without calling another function, so typically in these situations with tuples you'll see a nested "impl" function that does all the work. 我不知道你可以使用这种方法而不调用另一个函数的任何技术,所以通常在这些带有元组的情况下你会看到一个嵌套的“impl”函数来完成所有的工作。 Once you have the integer pack, you expand it while accessing the tuple (works for getting the values too). 获得整数包之后,在访问元组时展开它(用于获取值)。

On a stylistic note: use using , not typename , especially in template heavy code as the former can alias templates too. 在风格上注意:使用using而不是typename尤其是在模板繁重的代码中,因为前者也可以使用别名模板。 And don't use that enum trick to store a static value without it using space; 并且不使用该enum技巧来存储静态值而不使用空间; compilers will optimize this out anyhow and just using a static constexpr integer is much clearer. 编译器无论如何都会优化它,只需使用static constexpr整数static constexpr清楚了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从可变种类的模板类包中的每种类型中恢复非类型名模板参数? - How can a recover the non-typename template argument from each type in a variadic pack of template classes? 如何按索引从可变参数模板参数包中提取值? - How to extract a value from a variadic template parameter pack by index? 如何按类型派生过滤可变参数模板包? - How to filter a variadic template pack by type derivation? 将Lambda参数类型输入模板参数包 - Get lambda parameters type into template argument pack 在可变参数 function 模板中,可以从模板参数包元素中推断出返回类型 - In a variadic function template can the return type be deduced from the template parameter pack elements C ++如何将可变参数函数模板的参数包-&gt;包装到lambda中 - C++ how to wrap a variadic function template's parameter pack -> into a lambda 是否可以从函数模板返回可变参数lambda? - Is it possible to return a variadic lambda from a function template? 提取可变参数模板参数包并在类型特征元函数中的另一个可变参数模板中使用它? - Extract variadic template parameter pack and use it in another variadic template in a type traits meta-function? 如何提取/扩展可变参数模板参数 - How to extract/expand variadic template parameters 迭代可变参数模板的类型参数 - iterating over variadic template's type parameters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM