C++:闭包:闭包Closure理解

一:什么是闭包

闭包有很多定义,一种说法是:闭包是带有上下文的函数,说白了,就是有状态的函数,这其实就是一个类,换个名字而已。

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

函数是代码,状态是一组变量,将代码和变量捆绑(bind),就形成了闭包。

二:闭包的实现 

2.1:重载operator()

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

/**
	闭包的使用
*/

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

class MyFunctor
{
public:
	// 通过列表的形式初始化成员变量
	MyFunctor(int temp) :count(temp) {};

	// 重载operator()操作符
	int operator()(int temp) {
		return temp + count;
	}

public:
	int count;

private:

};

int main() {
	int count = 1;
	// 调用构造函数给成员变量赋值
	MyFunctor f(count);
	cout << "result: " << f(1) << endl;
}

2.2:Lambda表达式

int main() {
	int count = 1;
	// lambda表达式
	auto f_lambda = [=](int f)->int
	{
		return f + count;
	};
	cout << "f_lambda result: " << f_lambda(1) << endl;
}

点评: 通常  function<int(int)> f = [ ] (int x) {return x};

通常这个叫闭包。

闭包 [ ]  中可以添加 = 或者 & 两个运算符,查过 cpp reference后,这个叫 capture(捕获),即使用闭包外的变量方式。我们讨论下这两个运算符:

2.2.1:[=]() {} :这是对闭包外变量进行const 引用的形式,即不允许修改闭包外的变量 。

int main() {

    int count = 1;

    auto f_lambda1 = [=](int i)->int
    {
		count = 2;   // error: 表达式必须是可修改的左值(因为capture捕获的是const引用形式)
		return i + count;
    };

}

2.2.2:[&] () {}  : 这是对闭包外变量进行引用的形式,可以修改闭包外的变量,并且保留为修改后的值

int main() {

    int count = 1;

    auto f_lambda1 = [&](int i)->int
    {
		count = 2;   
		return i + count;
    };
    cout<< f_lambda1(2)<< endl;
    
}

// 打印结果:4

2.3:lambda表达式 

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

int func(int temp, int count) {
	return temp + count;
}

int main() {
	int count = 1;
	// 调用构造函数给成员变量赋值
	// MyFunctor f(count);
	// cout << "result: " << f(1) << endl;

	// lambda表达式
	/*auto f_lambda = [=](int f)->int
	{
		return f + count;
	};
	cout << "f_lambda result: " << f_lambda(1) << endl;*/

	// bind表达式
	function<int(int)> f_bind = bind(func, placeholders::_1, count);
	cout<< f_bind(3)<< endl;
}

猜你喜欢

转载自blog.csdn.net/u013620306/article/details/128561825
今日推荐