lambda 表达式是 C++ 11 中增加的特性,和 ObjC 中的 block 很相似,都是匿名函数。
两者语法很相似:
auto lambda = [] {
};
lambda();
auto block = ^ {
};
block();
不同点 1:
- lambda 内部不能直接使用外部变量,需要把变量添加到捕获列表
- block 则可以直接引用外部变量
NSMutableArray *array = NSMutableArray.array;
auto lambda = [array] {
[array addObject:@0];
};
auto block = ^ {
[array addObject:@1];
};
如果捕获的是 C++ 对象:
- lambda 可以调用类的 const 和非 const 方法
- block 只能调用类的 const 方法,除非使用
__block
修饰被捕获的对象 - lambda 不能捕获
__block
修饰的对象,编译会报错:__block variable 'xxx' cannot be captured in a lambda expression
CXXClass cxx;
__block CXXClass cxx2; // __block variable 'cxx2' cannot be captured in a lambda expression
auto lambda = [&cxx, &cxx2] {
cxx.foo(); // Ok
cxx2.foo(); // Error
};
class CXXClass {
public:
void foo() {}
};
CXXClass cxx;
__block CXXClass cxx2;
auto block = ^ {
cxx.foo(); // Error, foo() 是非 const 修饰的方法
cxx2.foo(); // Ok, 使用 __block 修饰后就没问题
};