OC 的 Block 和 C++ 的 Lambda

2015-08-10  本文已影响801人  贾佳菊

二者的定义:

Block :

^ return type (parameter list) {function body}

其中,返回类型的参数表时可以省略的,即最简略的方式:

^ {function body}

Lambda :

[capture list] (parameter list) -> return type {function body}

其中,返回类型和参数表也是可以省略的:

[capture list] {function body}

捕获(截获)变量

二者的定义出了使用的运算符不同之外, Lambda 还比 Block 多了一个 "capture list",即捕获列表,其实 Block 中也有对变量的捕获:

Block 中的捕获:如果要想在 Block 中截获一个变量,可以直接使用这个变量,但是此时使用的仅是这个变量的拷贝值,如果要在 Block 中修改这个变量,需要在变量之前使用

__block

来修饰。

Lambda 中的捕获:Lambda 捕获变量只针对于局部非 static 变量,如果要使用 static 变量或者使用定义在当前作用域的父级作用域的变量时,可以直接使用。要在 Lambda 中捕获的变量需在捕获列表里声明。并且,捕获分为“值捕获”和“引用捕获”,如果变量名为 value,
那么值捕获为:

[value]{}

引用捕获为:

[&value]{}

隐式捕获可以让编译器自动推断 Lambda 中要捕获的变量,隐式的值捕获:

[=]{}

隐式的引用捕获:

[&]{}

返回值

Block 的返回类型是可以省略的,而在 《C++ Primer》 中,关于 Lambda 的返回类型是这样说的:如果 Lambda 中含有除了 return 语句之外的其它语句,那么返回类型不可省略,但是实际测试下也是可以省略的,这个应该和编译器有关。

其它

Block “这是个位于 C 层面的特性,因此,只要有支持此特性的编译器,以及能执行块的运行期组件,就可以在 C、C++、Objective-C 、Objective-C++ 代码中使用它”(Effective Objective-C 2.0 第 149 页)
实际测试确实是这样,以下是一个简单的 CPP 程序:

int main(int argc, const char * argv[]) {

auto testLambda = [](int a , int b){
    
    if (a > b){
        return a;
    }
    else {
        return b;
    }
    
};

auto testBlock = ^(int a, int b){
    
    return (a > b) ? a : b;

};

std::cout << testLambda(5, 9) << std::endl;
std::cout << testBlock(5, 9) << std::endl;

return 0;

}

我们在 CPP 中同时使用了 Lambda 和 Block ,二者都打印了 9 。同时,还看到 Lambda 中含有除了 return 之外的其它语句而没有声明返回类型。

上一篇下一篇

猜你喜欢

热点阅读