为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
繁花不似锦 2019-06-18 16:45:38
能否计算出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对象在函数内部(如上面所示)。
查看完整描述

3 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

有意思,我刚写了一个function_traits实施基于 在C+0x中在lambda上专门化一个模板 可以给出参数类型。正如在这个问题的答案中所描述的,诀窍是使用decltype拉姆达operator().

template <typename T>struct function_traits    : public function_traits<decltype(&T::operator())>{};
// For generic types, directly use the result of the signature of its '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.
    };};// test code below:int main(){
    auto lambda = [](int i) { return long(i*10); };

    typedef function_traits<decltype(lambda)> traits;

    static_assert(std::is_same<long, traits::result_type>::value, "err");
    static_assert(std::is_same<int, traits::arg<0>::type>::value, "err");

    return 0;}

注意这个解决方案为类似于泛型lambda的[](auto x) {}.


查看完整回答
反对 回复 2019-06-18
?
动漫人物

TA贡献1815条经验 获得超10个赞

虽然我不确定这是否符合标准,理想编译了以下代码:

template< class > struct mem_type;template< class C, class T > struct mem_type< T C::* > {
  typedef T type;};template< class T > struct lambda_func_type {
  typedef typename mem_type< decltype( &T::operator() ) >::type type;};int main() {
  auto l = [](int i) { return long(i); };
  typedef lambda_func_type< decltype(l) >::type T;
  static_assert( std::is_same< T, long( int )const >::value, "" );}

但是,这只提供函数类型,因此必须从其中提取结果和参数类型。如果你能用boost::function_traitsresult_typearg1_type会达到目的。由于ideone似乎没有在C+11模式下提供提升,所以我无法发布实际的代码,对不起。


查看完整回答
反对 回复 2019-06-18
  • 3 回答
  • 0 关注
  • 695 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信