飞道的博客

C++ Lambda表达式详解

359人阅读  评论(0)

一、简介

C++11开始引入了Lambda表达式,可将lambda表达式视为包含公有operator()的匿名接口(或类),这样可以更方便的使用函数对象或创建匿名函数(类似Java的匿名内部类)。

二、Lambda表达式定义

lambda表达式的定义必须以方括号([])打头。这些方括号告诉编译器,接下来是一个lambda表达式。方括号后面是一个参数列表,该参数列表与不使用lambda表达式时提供给operator()的参数列表相同。

[capture list] (params list) mutable -> return type {
    function body }
  • capture list:捕获的外部变量列表,可以为空
  • params list:形参列表,可以省略,表示无参函数
  • mutable:mutable关键字,表示是否可以修改捕获的变量,一般用不上,可以省略
  • -> return type:明确返回类型,可以省略,省略时根据函数体的return语句返回的类型确定,无return则返回类型为void
  • function body:函数体,函数实现

三、capture list详解

1. [] 不捕获外部任何变量

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
    auto func = [](int i) {
    cout << i << endl; }; // 有一个形参i
    func(i);
}

2. [=] 捕获外部作用域所有变量的值,只读无法修改

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
    auto func = [=]() {
    cout << i << endl; }; // 没有形参,而且直接捕获的i的值
    func();
}

3. [&] 捕获外部作用域所有变量的引用,可修改捕获的变量

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
    auto func = [&]() {
    // 没有形参,而且直接捕获的i的引用
		cout << "修改前,i = " << i << endl;
		i++;
	};
    func();
	cout << "修改后,i = " << i << endl;
}

执行结果:

修改前,i = 1
修改后,i = 2

4. [var] 只捕获外部变量var的值,只读无法修改

5. [&var] 只捕获外部变量var的引用,可修改

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
    auto func = [i]() {
    cout << i << endl; }; // 只捕获的i的值
    func();
}

6. [this] 捕获当前类的this指针

例如:

#include <iostream>
using namespace std;

class Dog
{
   
public:
	int age = 1;
    void bark() {
    cout << "汪!" << endl; };

	void lambda() {
   
        auto fun = [this] {
    // 捕获this指针
            this->bark(); // 通过this指针调用bark()函数
			cout << "age = " << this->age << endl; // 通过this指针访问age变量
        };
        fun();
    }
};

int main()
{
   
    Dog dog;
	dog.lambda();
}

7. [=, &] 混合方式

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
	int j = 2;
	// [&, =j]() { // 变量j值方式捕获,其余变量捕获引用
    auto func = [=, &i]() {
    // 变量i引用方式捕获,其余变量值方式捕获
		cout << "j = " << j << endl;
		i++;
	};
    func();
	cout << "i = " << i << endl;
}

四、mutable关键字

mutable关键字说明函数体中可以修改值捕获的变量,但不会影响到外部变量的值,因为值传递是以拷贝的方式实现的。

例如:

#include <iostream>
using namespace std;

int main()
{
   
    int i = 1;
    auto func = [=] () mutable {
    // 不加mutable则编译报错,因为捕捉值时i是只读的
		i++;
		cout << "lambda内,i = " << i << endl;
	};
    func();
	cout << "lambda外,i = " << i << endl;
}

执行结果:

lambda内,i = 2
lambda外,i = 1

五、一些场景、例子

1. 排序

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
   
    vector<int> nums {
    3, 10, 5, 32, 1 };
	sort(nums.begin(), nums.end(), [](int a, int b) -> bool {
    return a < b; });
	cout << "max = " << nums[4] << endl;
}

2. 递归

使用C++11新特性的function来接收lambda表达式,两者是等价的。

例如求 1 到 n 的和:

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

int main()
{
   
    std::function<int(int)> func = [&func](int n) {
    
		return n <= 1 ? 1 : func(n - 1) + n; 
	};
	cout << "func(3) = " << func(3) << endl;
	cout << "func(10) = " << func(10) << endl;
}

执行结果:

func(3) = 6
func(10) = 55

转载:https://blog.csdn.net/afei__/article/details/116161236
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场