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,它基本上是一种类型擦除包装器,将具有相同签名的不同仿函数聚集在一起形成共同类型.它是静态多态与模板之间的桥梁,以及如果要注册回调所需的动态多态,将其存储以供日后使用,然后在不"记住"原始类型的情况下调用它.
void registerCallback(const std::function<void(int)>& callback);
Run Code Online (Sandbox Code Playgroud)
考虑使用功能模板.有很多好的理由,例如重载时更好的行为(重载std::function是痛苦的):
template<typename Functor>
void registerCallback(Functor&& functor);
Run Code Online (Sandbox Code Playgroud)
(您也可以接受参数Functor functor,这不太重要.)
如果代码需要例如存储functor后者,则可能会将其保存在内部std::function.你想要避免的std::function是功能参数.
| 归档时间: |
|
| 查看次数: |
3463 次 |
| 最近记录: |