能否计算出lambda的参数类型和返回类型?

能否计算出lambda的参数类型和返回类型?

给定一个lambda,是否可以确定它的参数类型和返回类型?如果是,怎么做?

基本上,我想lambda_traits可以下列方式使用:

auto lambda = [](int i) { return long(i*10); };lambda_traits<decltype(lambda)>::param_type  i; 
//i should be intlambda_traits<decltype(lambda)>::return_type l; //l should be long

背后的动机是我想用lambda_traits在接受lambda作为参数的函数模板中,我需要知道它在函数中的参数类型和返回类型:

template<typename TLambda>void f(TLambda lambda){
   typedef typename lambda_traits<TLambda>::param_type  P;
   typedef typename lambda_traits<TLambda>::return_type R;

   std::function<R(P)> fun = lambda; //I want to do this!
   //...}

目前,我们可以假设lambda只使用一个参数。

一开始,我试着和std::function作为:

template<typename T>A<T> f(std::function<bool(T)> fun){
   return A<T>(fun);}f([](int){return true;}); //error

但很明显会出错。所以我把它改成TLambda函数模板的版本,并希望构造std::function对象在函数内部(如上面所示)。


繁花不似锦
浏览 700回答 3
3回答

守着一只汪

有意思,我刚写了一个function_traits实施基于&nbsp;在C+0x中在lambda上专门化一个模板&nbsp;可以给出参数类型。正如在这个问题的答案中所描述的,诀窍是使用decltype拉姆达operator().template&nbsp;<typename&nbsp;T>struct&nbsp;function_traits&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;public&nbsp;function_traits<decltype(&T::operator())>{}; //&nbsp;For&nbsp;generic&nbsp;types,&nbsp;directly&nbsp;use&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;signature&nbsp;of&nbsp;its&nbsp;'operator()'template&nbsp; <typename&nbsp;ClassType,&nbsp;typename&nbsp;ReturnType,&nbsp;typename...&nbsp;Args>struct&nbsp;function_traits<ReturnType(ClassType::*)(Args...)&nbsp;const> //&nbsp;we&nbsp;specialize&nbsp;for&nbsp;pointers&nbsp;to&nbsp;member&nbsp;function{ &nbsp;&nbsp;&nbsp;&nbsp;enum&nbsp;{&nbsp;arity&nbsp;=&nbsp;sizeof...(Args)&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;arity&nbsp;is&nbsp;the&nbsp;number&nbsp;of&nbsp;arguments. &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ReturnType&nbsp;result_type; &nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;<size_t&nbsp;i> &nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;arg&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;std::tuple_element<i,&nbsp;std::tuple<Args...>>::type&nbsp;type; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;the&nbsp;i-th&nbsp;argument&nbsp;is&nbsp;equivalent&nbsp;to&nbsp;the&nbsp;i-th&nbsp;tuple&nbsp;element&nbsp;of&nbsp;a&nbsp;tuple &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;composed&nbsp;of&nbsp;those&nbsp;arguments. &nbsp;&nbsp;&nbsp;&nbsp;};};//&nbsp;test&nbsp;code&nbsp;below:int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;auto&nbsp;lambda&nbsp;=&nbsp;[](int&nbsp;i)&nbsp;{&nbsp;return&nbsp;long(i*10);&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;function_traits<decltype(lambda)>&nbsp;traits; &nbsp;&nbsp;&nbsp;&nbsp;static_assert(std::is_same<long,&nbsp;traits::result_type>::value,&nbsp;"err"); &nbsp;&nbsp;&nbsp;&nbsp;static_assert(std::is_same<int,&nbsp;traits::arg<0>::type>::value,&nbsp;"err"); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}注意这个解决方案不为类似于泛型lambda的[](auto x) {}.

动漫人物

虽然我不确定这是否符合标准,理想编译了以下代码:template<&nbsp;class&nbsp;>&nbsp;struct&nbsp;mem_type;template<&nbsp;class&nbsp;C,&nbsp;class&nbsp;T&nbsp;>&nbsp;struct&nbsp;mem_type<&nbsp;T&nbsp;C::*&nbsp;>&nbsp;{ &nbsp;&nbsp;typedef&nbsp;T&nbsp;type;};template<&nbsp;class&nbsp;T&nbsp;>&nbsp;struct&nbsp;lambda_func_type&nbsp;{ &nbsp;&nbsp;typedef&nbsp;typename&nbsp;mem_type<&nbsp;decltype(&nbsp;&T::operator()&nbsp;)&nbsp;>::type&nbsp;type;};int&nbsp;main()&nbsp;{ &nbsp;&nbsp;auto&nbsp;l&nbsp;=&nbsp;[](int&nbsp;i)&nbsp;{&nbsp;return&nbsp;long(i);&nbsp;}; &nbsp;&nbsp;typedef&nbsp;lambda_func_type<&nbsp;decltype(l)&nbsp;>::type&nbsp;T; &nbsp;&nbsp;static_assert(&nbsp;std::is_same<&nbsp;T,&nbsp;long(&nbsp;int&nbsp;)const&nbsp;>::value,&nbsp;""&nbsp;);}但是,这只提供函数类型,因此必须从其中提取结果和参数类型。如果你能用boost::function_traits,&nbsp;result_type和arg1_type会达到目的。由于ideone似乎没有在C+11模式下提供提升,所以我无法发布实际的代码,对不起。
打开App,查看更多内容
随时随地看视频慕课网APP