C ++ 11 lambda函数作为回调和默认值

时间:2014-01-28 20:15:25

标签: templates c++11 lambda

我想将lambda函数传递给另一个函数:

template<typename T>     
void test2(T fn){
    fn();
}

test2([]{cout<<"Hi"});

但我也想在test2中使用默认的空函数。所以我做下一个:

auto empty_lambda = []{};

template<typename T = decltype(empty_lambda)>
void test(T fn = empty_lambda){
    fn();
}

test();

一切都很好,但我不能把

  

auto empty_lambda = [] {};

在课堂内,所以我必须将它保持在全球范围内。

我能以某种方式改善这种情况吗?除void test2(){ test2([]{}); }

选项外

2 个答案:

答案 0 :(得分:1)

如果它 不是lambda,你可以more portably use a plain-old static member function

class foo {
    static void do_nothing() {}
public:
    template<typename T = decltype(do_nothing)>
    void test(T fn = do_nothing){
        fn();
    }
};

但是如果你真的想要lambda语法,你可以利用隐式转换为函数指针:

class foo {
public:
    template<typename T = void(*)()>
    void test(T fn = []{}){
        fn();
    }
};

RETRACTION:原始答案是不可移植的,标准没有指定任何lambda闭包具有文字类型,以便可以在常量表达式中使用。

信不信由你,你可以使用auto声明一个静态数据成员(根据C ++11§[dcl.spec.auto] / 4):

class foo {
    static constexpr auto empty_lambda = []{};
public:
    template<typename T = decltype(empty_lambda)>
    void test(T fn = empty_lambda){
        fn();
    }
};

constexpr decltype(foo::empty_lambda) foo::empty_lambda;

constexpr静态数据成员的定义 - 至少可以说是凌乱的。 (Live code at Coliru)。

答案 1 :(得分:0)

您可以使用std::function,如下所示:

class X
{
   static std::function<void()> f;

   template<typename T = decltype(f)>
   void test(T fn = f){
       fn();
   }
};

std::function<void()> X::f = []{};

请参阅HERE