美文网首页CPP
C++ 闭包的理解

C++ 闭包的理解

作者: 顽强的猫尾草 | 来源:发表于2018-09-26 09:21 被阅读61次

闭包有很多种定义,一种说法是,闭包是带有上下文的函数。说白了,就是有状态的函数。更直接一些,不就是个类吗?换了个名字而已。

一个函数, 带上了一个状态, 就变成了闭包了。什么叫 "带上状态" 呢? 意思是这个闭包有属于自己的变量,这些个变量的值是创建闭包的时候设置的,并在调用闭包的时候,可以访问这些变量。

函数是代码,状态是一组变量,将代码和一组变量捆绑,就形成了闭包,内部包含 static 变量的函数不是闭包,因为这个 static 变量不能捆绑。闭包的状态捆绑,必须发生在运行时。

闭包的实现

重载 operator()

因为闭包是一个函数 + 一个状态, 这个状态通过隐含的 this 指针传入,所以闭包必然是一个函数对象,因为成员变量就是极好的用于保存状态的工具,因此实现 operator() 运算符重载,该类的对象就能作为闭包使用。默认传入的 this 指针提供了访问成员变量的途径。

#include <iostream>
using namespace std;

class MyFunctor {
public:
    MyFunctor(int tmp) : round(tmp) {}
    int operator()(int tmp) { return tmp + round; }
private:
    int round;
};

int main() {
    int round = 2;
    MyFunctor f(round);    // 调用构造函数
    cout << "result = " << f(1) << endl;    // operator()(int tmp)
    return 0;
}

输出:

result = 3

lambda 表达式

C++11 里提供的 lambda 表达式 就是很好的语法糖,其本质和手写的函数对象没有区别。

lambda 表达式完整的声明格式如下:
[capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下:

  • capture list:捕获外部变量列表
  • params list:形参列表
  • mutable 指示符:用来声明是否可以修改捕获的变量
  • exception:异常设定
  • return type:返回类型
  • function body:函数体

示例代码:

int main() {
    int round = 2;
    auto f = [=](int f) -> int { return f + round; } ;
    cout << "result = " << f(1) << endl;
    return 0;
}    

输出:

result = 3

隐式捕获
为了指示编译器推断捕获列表,我们可以在捕获列表中写一个 &=& 告诉编译器采用引用捕获,= 则为值捕获。

std::bind

标准库提供的 bind 是更加强大的语法糖,将手写需要很多很多代码的闭包,浓缩到一行 bind 就可以搞定了。

#include <iostream>
#include <functional>
using namespace std;

int func(int tmp, int round) {
    return tmp + round;
}

int main()
{
    using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

    int round = 2;
    std::function<int(int)> f = std::bind(func, _1, round);
    cout << "result = " << f(1) << endl;
    return 0;
}

输出:

result = 3

参考:
[1] C++ 闭包(closure)
[2] C++ 11 Lambda表达式
[3] 泛型--lambda表达式捕获

相关文章

  • 第七章 闭包

    c++没有闭包,swift有闭包。c++有些类似的概念是Lambda函数,但是闭包概念更丰富,更完善,更灵活。 闭...

  • JavaScript闭包的理解

    前言 在JavaScript中,闭包对于JavaScript的意义无异于指针在c++中的意义。理解闭包是我们掌握J...

  • C++ 闭包的理解

    闭包有很多种定义,一种说法是,闭包是带有上下文的函数。说白了,就是有状态的函数。更直接一些,不就是个类吗?换了个名...

  • Gradle开发-Groovy闭包

    # 闭包 闭包的基础知识 闭包的使用 闭包 this,owner,delegate 的理解 总结 ## 闭包的基础...

  • Swift5 闭包及其应用

    关于如何理解闭包 学习闭包的第一个难点就是理解闭包,可能很多人用了很久的闭包都还不太清楚闭包到底是什么,我这里提供...

  • 【js基础修炼之路】— 深入浅出理解闭包

    之前对于闭包的理解只是很肤浅的,只是浮于表面,这次深究了一下闭包,下面是我对闭包的理解。 什么是闭包? 引用高程里...

  • c++ 闭包(closure)

     测试c++的闭包功能。代码抄自webrtc。

  • JS闭包理解

    闭包的概念 闭包就是能够读取其他函数内部变量的函数。 一、变量的作用域 要理解闭包,首先必须理解Javascrip...

  • 自动闭包/逃逸闭包/非逃逸闭包

    自动闭包、逃逸闭包和非逃逸闭包三个概念有些不好理解,这里按我自己的理解总结一下,不对的地方请指正 一、非逃逸闭包:...

  • 闭包理解

    这次我发现了个奇怪的问题,高程经典的闭包陷阱,竟然是把一个未执行的函数赋值给了一个数组项,当年的我太年轻,竟然没看...

网友评论

    本文标题:C++ 闭包的理解

    本文链接:https://www.haomeiwen.com/subject/jlqroftx.html