Objective-C++ 11 - 为什么我们不能将块分配给lambda?

Ric*_*III 15 c++ lambda objective-c objective-c++ c++11

所以,我刚刚升级到Xcode 4.4,我注意到在更改日志中:

Apple LLVM编译器支持其他C++ 11功能,包括lambdas

哪个太棒了!所以我开始编码,我找到了一些东西:

  1. Lambdas可分配给Objective-C块:

    void (^block)() = []() -> void { 
        NSLog(@"Inside Lambda called as block!");
    };
    
    block();
    
    Run Code Online (Sandbox Code Playgroud)
  2. std::function 可以持有Objective-C块:

    std::function<void(void)> func = ^{
        NSLog(@"Block inside std::function");
    };
    
    func();
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我们不能将一个Objective-C块分配给lambda:

    auto lambda = []() -> {
        NSLog(@"Lambda!");
    };
    
    lambda = ^{ // error!
        NSLog(@"Block!");
    };
    
    lambda();
    
    Run Code Online (Sandbox Code Playgroud)

为什么是这样?鉴于我们上面所看到的,这两者在语义上是否应该是等价的?

ken*_*ytm 15

C++ 11的lambda的复制赋值运算符被明确禁用1.这不是"语义上等同"的问题.它甚至无法回归自身.更不用说无关的类型了.

#include <cstdio>
#include <type_traits>

int main() {
    auto lambda1 = []() -> void { printf("Lambda 1!\n"); };
    lambda1 = lambda1;  // error: use of deleted function ‘main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)’
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

std::function 可以持有Objective-C块.

  • std::function可以包含任何可以调用的类型f(a,b,c,...).由于块支持"调用操作符",因此它也可以由a持有std::function.但请注意,Objective-C和C++遵循不同的内存管理方案,因此std::function长时间存储块可能会导致悬空引用.

Lambdas可分配给Objective-C块:


1:C++11§5.1.2/ 19:

lambda表达式关联的闭包类型具有已删除(8.4.3)的默认构造函数和已删除的复制赋值运算符.

2:http://llvm.org/viewvc/llvm-project?view = evv &revision = 150620