C++ 0x lambda,我怎么能作为参数传递?

min*_*ang 17 c++ lambda c++11

请查看以下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);
};
Run Code Online (Sandbox Code Playgroud)

我得到一个错误(在Visual Studio 2010中),lambda无法转换为类型WEIGHT_FUNC.我也知道答案:使用std::function object:

typedef std::function<uint64_t (void*)>  WEIGHT_FUNC;
Run Code Online (Sandbox Code Playgroud)

但是,我也想知道如何在不使用的情况下接收lambda的类型std::function.它应该是什么类型的?

Geo*_*che 20

转换为函数指针是相对较新的:它于2010年2月15日与N3043一起推出.

虽然例如GCC 4.5实现了它,但Visual Studio 10于2010年4月12日发布,因此没有及时实现.正如詹姆斯指出的那样,这在未来的版本中修复.

目前,您必须使用此处提供的替代解决方案之一.

技术上类似下面的解决方法会起作用,但没有可变参数模板它没有乐趣将它概括(Boost.PP到救援......)并且没有安全网反对传递捕获lambdas:

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; });
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,转换为函数指针仅适用于无状态lambda函数,它们无法捕获词法范围. (8认同)