C++小知识——lambda表达式

一、lambda表达式的定义

lambda表达式是C++11的重要特性之一,有如下特点:
1)声明式的编程风格:就地匿名定义目标函数或者函数,不需要额外写一个命名函数或者函数对象,以更直接的方式写程序。
2) 简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散。
3) 在需要的时间和地点实现功能闭包,使程序更加灵活。

1、定义形式

lambda表达式以下面的形式定义一个匿名函数,并且可以通过[]内的参数来捕获一定范围内的变量

[capture] (params) opt -> ret {body};
  • capture——捕获列表
  • params——参数列表
  • opt——函数选项
  • ret——返回值类型由后置语法来定义,可省略,通过return语句来自动推导
  • body——函数体

二、捕捉形式

通过方括号内的捕捉列表,可以捕获一定范围内的变量:

  • []不捕获任何变量
  • [&]捕获外部作用域所有变量,并作为引用在函数体使用(按引用捕获);
  • [=]捕获外部作用域作用变量,并作为副本在函数体使用(按值捕获);
  • [=,&foo]按值捕获外部作用域所有变量,并按引用捕获foo变量
  • [bar]按值捕获bar变量,同时不捕获其他变量
  • [this]捕获当前类中的this指针,让lambda拥有和当前类成员函数同样的访问权限,如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lambda中使用当前类的成员函数和成员变量。

三、使用

3.1 简单的封包例子

#include <iostream>

int main(int argc, char* argv[]){
	std::cout << "基本使用:[](int a) -> int {return a + 1; } " << std::endl;
	auto f = [](int a) -> int {return a + 1; };
	std::cout << "f(1) = " << f(1) << std::endl;

	std::cout << std::endl;

	std::cout << "省略返回值类型,由return语句自动推导:[](int a) {return a + 1; } " << std::endl;
	auto f_ = [](int a){return a + 1; };
	std::cout << "f_(2) = " << f_(2) << std::endl;

	return 0;
}

在这里插入图片描述

3.2 捕获参数的说明

3.2.1 在类内的使用

在这里插入图片描述

3.2.2 正常使用

在这里插入图片描述
所以,在使用的时候,默认状态下的lambda表达式无法修改通过复制方式捕获的外部变量,如果希望修改这些变量,需要用引用的方式进行修改

3.3举个sort函数的例子

比如,我要实现一个降序的比较,可能需要写一个cmp类,然后去重载()操作符,让cmp对象去调用它

#include <iostream>
#include <algorithm>
#include <vector>

class cmp {
public:
	bool operator()(const int &a, const int &b) {
		return a > b;
	}
};

template <class T>
void print(const std::vector<T>& vT) {
	for (auto i : vT)
		std::cout << i << " ";
	std::cout << std::endl;
}

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

	std::vector<int> ivec{ 1, 2, 4, 6, 3, 7, 5 };

	std::cout << "排序前: \n";
	print(ivec);

	std::sort(ivec.begin(), ivec.end(), cmp());
	std::cout << "排序后: \n";
	print(ivec);

	return 0;
}

用上面的方式,或者是使用自定义函数,会显得很繁琐,那么这个时候,其实就可以用lambda表达式代替它们

#include <iostream>
#include <algorithm>
#include <vector>

template <class T>
void print(const std::vector<T>& vT) {
	for (auto i : vT)
		std::cout << i << " ";
	std::cout << std::endl;
}

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

	std::vector<int> ivec{ 1, 2, 4, 6, 3, 7, 5 };

	std::cout << "排序前: \n";
	print(ivec);

	std::sort(ivec.begin(), ivec.end(), 
			[](const int &a, const int &b)->bool{return a > b; });

	std::cout << "排序后: \n";
	print(ivec);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CSDN_dzh/article/details/83615389