代码之家  ›  专栏  ›  技术社区  ›  minjang

C++ 0xlambda,如何传递参数?

  •  17
  • minjang  · 技术社区  · 16 年前

    请看下面的C++ 0xlambda相关代码:

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

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

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

    但是,我还想知道如何不使用 std::function . 它应该是什么类型?

    3 回复  |  直到 16 年前
        1
  •  20
  •   Georg Fritzsche    16 年前

    到函数指针的转换相对较新:它是用 N3043 2010年2月15日。

    在gcc 4.5实现它的同时,Visual Studio 10于2010年4月12日发布,因此没有及时实现。正如詹姆斯指出的,这个 will be fixed 在未来的版本中。

    目前,您必须使用这里提供的备选解决方案之一。

    从技术上讲,类似于以下解决方案的方法是可行的,但如果没有可变模板,将其概括(boost.pp to the rescue…)是没有乐趣的,而且没有安全网防止在以下情况下通过捕获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; });
    
        2
  •  1
  •   Edward Strange    16 年前

    如果你真的坚持不使用 function<> 然后您可能会使用decltype:

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

    不过,我真的不推荐这样做,因为你对自己有很大的限制,我甚至不知道两个具有相同签名的lambda是否保证是同一类型。

        3
  •  -1
  •   Klaim    16 年前

    尝试(未测试):

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

    我认为除了使用std::函数或等效函数之外,没有其他方法可以做到这一点。