C++ 11 lambda的参数/存储类型

flu*_*ffy 11 c++ lambda closures c++11

在C++ 11中,如何声明一个将lambda表达式作为参数的函数?我可以在网上找到大量资源来声明lambdas或将它们作为模板参数,但我真正想做的是能够使用lambdas作为易于声明的回调处理程序,类似于闭包所能实现的在Objective-C中的JavaScript和代码块中.

基本上,我想用lambda替换的经典C++构造是这样的:

class MyCallback {
public:
    virtual ~MyCallback() {}
    virtual void operator(int arg) = 0;
};

void registerCallback(const std::shared_ptr<MyCallback> &);

void foo(void) {
    int a, b, c;
    class LocalCallback: public MyCallback {
        int a, b, c;
    public:
        LocalCallback(int a, int b, int c): a(a), b(b), c(c) {}
        void operator(int arg) { std::cout << (a+b+c)*arg << std::endl; }
    };
    registerCallback(std::shared_ptr<MyCallback>(new LocalCallback(a,b,c)));
}
Run Code Online (Sandbox Code Playgroud)

这将被简化为:

void registerCallback(/* WHAT GOES HERE? */);

void foo(void) {
    int a, b, c;
    registerCallback([=](int arg){std::cout << (a+b+c)*arg << std::endl; })
}
Run Code Online (Sandbox Code Playgroud)

那么,我写的是/* WHAT GOES HERE? */什么?

编辑:这是为了存储一个稍后要回调的回调,而不是立即使用和调用它.

Ste*_*sop 19

通常const std::function<void(int)> &std::function<void(int)>.

我不确定判断是关于是std::function应该通过const引用还是通过值传递的.可能价值很好,特别是因为你打算将它复制到商店.

如果在所有语法的中间不清楚,void(int)则是函数类型,并且std::function<T>大约是"具有与类型T的函数相同的签名的函子".

Lambdas本身有匿名类型.无法命名lambda表达式的类型,并且具有相同签名的不同lambda表达式的类型不同:

auto foo = [=](int arg){std::cout << (a+b+c)*arg << std::endl; };
auto bar = [=](int arg){std::cout << (a+b+c)*arg << std::endl; };
// foo and bar have different types, accessible as decltype(foo), decltype(bar)
Run Code Online (Sandbox Code Playgroud)

因此需要std::function,它基本上是一种类型擦除包装器,将具有相同签名的不同仿函数聚集在一起形成共同类型.它是静态多态与模板之间的桥梁,以及如果要注册回调所需的动态多态,将其存储以供日后使用,然后在不"记住"原始类型的情况下调用它.


nos*_*sid 7

void registerCallback(const std::function<void(int)>& callback);
Run Code Online (Sandbox Code Playgroud)


Luc*_*ton 5

考虑使用功能模板.有很多好的理由,例如重载时更好的行为(重载std::function是痛苦的):

template<typename Functor>
void registerCallback(Functor&& functor);
Run Code Online (Sandbox Code Playgroud)

(您也可以接受参数Functor functor,这不太重要.)

如果代码需要例如存储functor后者,可能会将其保存在内部std::function.你想要避免的std::function是功能参数.