C++11-17中的lambda

本文详细介绍了C++11-17中的lambda表达式,包括可调用对象、谓词、lambda的捕捉列表、可变lambda、异常说明、指定返回类型等特性,并通过实例解析了如何使用lambda实现特定功能,如一元和二元谓词,以及如何处理捕捉列表中的值捕获和引用捕获。同时,文章提到了泛型lambda、constexpr lambda和向lambda传递this的拷贝等C++14和C++17的新特性。
摘要由CSDN通过智能技术生成

可调用对象

  可调用对象,有函数、函数指针、重载了函数调用运算符的类(也就是仿函数)、lambda表达式四种形式。这里主要介绍lambda的作用。

谓词

  先看下面的代码:

static bool cmp(const int& a, const int& b) {
    return a > b; }
int main() {
   
	vector<int> arr{
    1, 4, 5, 2 };
	sort(arr.begin(), arr.end(), cmp);
	for (auto w : arr) {
   
		cout << w << " ";
	}
}

  由于STL中的sort函数默认是less(升序排序),这里为了演示就调用了sort的重载版本,传入一个二元谓词版本。这里先解释下谓词是什么?
  谓词是一个可调用的表达式(也就是可调用对象),其返回结果是一个能用作条件的值。标准库算符所使用的谓词分为:一元谓词(只接受单一参数),和二元谓词(接受两个参数),没有三元、四元谓词。接受谓词参数的算法对输入序列中的元素调用谓词。因此,元素类型必须能转换为谓词的参数类型。
  这里再来看上面的cmp函数为什么要加static声明,其实在上面的例子中加不加都能通过。但是最好还是加上,因为如果在一个类中定义了cmp函数,如果在成员函数中调用这个带谓词的sort函数会调用失败,因为std::sort是一个全局函数,其传入的谓词要是全局或者是静态的。
  由于谓词只有一元和二元之分,那么有时候希望进行的操作需要更多的参数,超出了算法对谓词的限制。下面有个需求,找出vector中字符长度大于length的第一个元素。find_if是find的一元谓词版本,其需要一对迭代器和一元谓词,该函数返回第一个使谓词返回非0值得元素,如果不存在这样得元素,则返回尾迭代器。

static bool cmp(const string& s) {
    return s.size() < 4; }
int main() {
   
	vector<string> arr{
    "hello", "world!", "C++", "Welcome", "you" };
	auto it = find_if(arr.begin(), arr.end(), cmp);
	cout << *it << endl;
}
// 结果显式:C++

  这里规定了比较的长度为4,如果想传入一个长度变量怎么办?但是STL规定了传递给find_if任何函数都必须严格接受一个参数,所以没有任何办法能传递给它两个参数。下面可以用lambda来实现(lambda也是传入一个参数,但是其通过其它功能来得到长度变量)

lambda

  lambda可以理解成一个未命名的内联函数。与任何函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数体。但是与别的函数不同,lambda可能定义在函数内部。

[capture list](parameter list)  mutable或异常exception ->return type {
    function body }
  • [capture list]:捕获列表,是一个lambda所在函数中可以访问的变量的列表(通常为空)。其总是出现在lambda函数的开始处。事实上,[]是lambda引出符。编译器根据该引出符判断接下来的代码是否是lambda函数。
  • (parameter list):参数列表,与普通函数一样,但是如果不需要参数传递,则可以连同括号()一起省略。
  • mutable:修饰符,默认情况下lambda捕获的变量是按值传递的,不能被改变,如果加上mutable修饰符可以改变其变量。在使用该修饰符时,参数列表不可省略。
  • 异常说明exception:用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。
  • ->return-type:返回类型。处于方便,不需要返回值的时候也可以连同符号->一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
  • { function body }:函数体。内容与普通函数一样,不过除了可以使用参数之外,还以可以使用所有捕获的变量。
      下面先通过lambda实现上述的find_if,然后在根据lambda形式介绍各个部分。
int main() {
   
	int length = 4;
	vector<string> arr{
    "hello", "world!", "C++", "Welcome", "you" };
	auto lambda = [length](string& s) {
    return s.size() < length; };
	auto it = find_if(arr.begin()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值