Objective-C++ 11 - Why can't we assign a block to a lambda?
所以,我刚升级到xcode 4.4,我在变更日志中注意到:
Apple LLVM compiler supports additional C++11 features, including lambdas
太棒了!所以我开始编码,我发现了一些事情:
lambda可分配给objective-c块:
1 2 3 4 5 | void (^block)() = []() -> void { NSLog(@"Inside Lambda called as block!"); }; block(); |
1 2 3 4 5 | std::function<void(void)> func = ^{ NSLog(@"Block inside std::function"); }; func(); |
我们无法将Objective-C块分配给lambda:
1 2 3 4 5 6 7 8 9 | auto lambda = []() -> { NSLog(@"Lambda!"); }; lambda = ^{ // error! NSLog(@"Block!"); }; lambda(); |
为什么会这样?考虑到我们上面所看到的,这两者在语义上不应该是等价的吗?
C++ 11的lambda拷贝赋值运算符是显式禁用的。这不是"语义等价"的问题。它甚至不能重新分配给自己。更不用说一个不相关的类型。
1 2 3 4 5 6 7 8 9 | #include <cstdio> #include <type_traits> int main() { auto lambda1 = []() -> void { printf("Lambda 1! "); }; lambda1 = lambda1; // error: use of deleted function ‘main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)’ return 0; } |
std::function 可以保存任何可以作为f(a,b,c,...) 调用的类型。由于块支持"invoke操作符",因此它也可以由std::function 持有。但是注意Objy-C和C++遵循不同的内存管理方案,所以在EDCOX1 0中存储一个块可能会导致悬空引用。
lambda可分配给objective-c块:
- 责怪Sahchandler2:)。不过,它还没有记录在案。
1:C++ 11节5.1.2/19:
The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted copy assignment operator.
2:http://llvm.org/viewvc/llvm-project?视图=修订版&修订版=150620
LAMBDAS有各自的、实现定义的类型,它们对每个lambda都是特定的。下面的代码也是一个错误:
1 2 3 | auto l1=[](){return 1;} auto l2=[](){return 2;} l1=l2; //Error |