简体   繁体   English

C ++ 0x Lambda,如何作为参数传递?

[英]C++0x lambda, how can I pass as a parameter?

Please look at the following C++0x lambda related code: 请查看以下与C ++ 0x lambda相关的代码:

typedef uint64_t (*WEIGHT_FUNC)(void* param);
typedef std::map<std::string, WEIGHT_FUNC> CallbackTable;

CallbackTable table;
table["rand_weight"] = [](void* param) -> uint64_t
{
  return (rand() % 100 + 1);
};

I got an error (in Visual Studio 2010) that the lambda couldn't be converted to the type of WEIGHT_FUNC . 我收到一个错误(在Visual Studio 2010中),无法将lambda转换为WEIGHT_FUNC的类型。 I also know the answer: using std::function object : 我也知道答案:使用std::function object

typedef std::function<uint64_t (void*)>  WEIGHT_FUNC;

However, I also want to know how I can receive the type of lambda WITHOUT using std::function . 但是,我也想知道如何在不使用std::function接收lambda类型。 What type should it be? 应该是什么类型?

The conversion to function pointer is relatively new: It was introduced with N3043 on February 15, 2010. 向函数指针的转换相对较新:2010年2月15日与N3043一起引入。

While eg GCC 4.5 implements it, Visual Studio 10 was released on April 12, 2010 and thus just didn't implement it in time. 例如,虽然GCC 4.5实现了它,但Visual Studio 10于2010年4月12日发布,因此没有及时实现。 As James pointed out, this will be fixed in future releases. 正如James指出的那样,此问题在以后的版本中修复

For the moment you have to use one of the alternative solutions provided here. 目前,您必须使用此处提供的替代解决方案之一。

Technically something like the following workaround would work, but without variadic templates its no fun to generalize it (Boost.PP to the rescue...) and there is no safety net against passing capturing lambdas in: 从技术上讲,可以使用以下解决方法,但没有可变参数的模板,将其推广(将Boost.PP应用于救援...)就没有意思,并且没有安全网可以阻止捕获的lambda传入:

typedef uint64_t (*WeightFunc)(void* param);

template<class Func> WeightFunc make_function_pointer(Func& f) {
    return lambda_wrapper<Func>::get_function_pointer(f);
}

template<class F> class lambda_wrapper {
    static F* func_;
    static uint64_t func(void* p) { return (*func_)(p); }    
    friend WeightFunc make_function_pointer<>(F& f);    
    static WeightFunc get_function_pointer(F& f) {
        if (!func_) func_ = new F(f);
        return func;
    }
};

template<class F> F* lambda_wrapper<F>::func_ = 0;

// ...
WeightFunc fp = make_function_pointer([](void* param) -> uint64_t { return 0; });

If you really insist on not using function<> then you could probably use decltype: 如果您确实坚持不使用function<>则可以使用decltype:

typedef decltype([](void*)->uint_64{return 0;}) my_lambda_type;

I really don't recommend this though since you're drastically limiting yourself and I don't even know if two lambda's with the same signature are guaranteed to be the same type. 我真的不建议这样做,因为您要严格限制自己,而且我什至不知道两个具有相同签名的lambda是否保证为同一类型。

Try with (not tested) : 尝试(未测试):

#include <function>

typedef std::function< int64_t (void*) > weight_func;
typedef std::map<std::string, weight_func > CallbackTable;

I don't think there is any other way to do this than to use std::function or equivalent. 我认为除了使用std :: function或等效方法外,没有其他方法可以做到这一点。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM