Not Only Algorithm,不仅仅是算法,关注数学、算法、数据结构、程序员笔试面试以及一切涉及计算机编程之美的内容 。。
你的位置:NoAlGo博客 » 程序设计 » ,

C++11中的lambda表达式

lambda表达式是C++11新增加的一个特性,其允许程序员定义匿名函数,该函数一般比较短小,一次性执行,这样既方便了编程,又能防止外部访问。
本文将通过几个简单的例子说明lambda表达式的使用方法。

简介

lambda表达式的定义如下:

[capture] (parameters) mutable -> return_type { statement }

中括号内的Capture表示捕获列表,它由多个捕获项组成,并以逗号分开,捕获列表有如下几种形式:

  • [var]: 表示以值传递方式捕获变量var
  • [&var]:表示以引用方式捕获变量var
  • [=]: 表示以值传递方式捕获所有父作用域的变量
  • [&]: 表示以引用传递捕获所有父作用域的变量
  • [this]:表示以值传递方式捕获当前的this指针

另外,可以把不同的捕获方式组合进行使用:

  • [&a, b]:表示以引用的方式捕获变量a,以值传递方式捕获变量b
  • [=, &a]:表示以值传递方式捕获所有父作用域的变量,而a以引用方式捕获
  • [&, a]: 表示以引用方式捕获所有父作用域的变量,而a以值传递方式捕获
  • [a, =]: 错误,需要先指明默认的捕获方式

小括号内的Parameters表示参数列表。这与普通函数的参数列表一致。如果不需要参数传递,则可以省略()。

接下来的mutable声明,事实上这里可以是以下三种声明之一,并且可以省略。

  • mutable: 说明lambda表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的non-const方法。
  • exception:表明lambda表达式是否抛出异常以及抛出何种异常。
  • attribute:声明属性。

接下来的return_type表示函数的返回类型,与普通函数的返回类型一致。当没有返回值时可以连同->一起省略。

最后的statement表示函数体,与普通函数一致,不过除了使用参数之外,还可以使用所有捕获的变量,而且对以引用方式捕获的变量的修改会影响外部的变量本身。

例子

以下通过一些简单的例子说明C++中lambda表达式的使用方法。
首先包含必要的头文件。

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

下面是一个最简单的lambda表达式,其实际上什么事也没有做,但是合法的C++代码。

void test1()
{
	[](){}();
}

下面是一个Hello World版本的lambda表达式。

void test2()
{
	[](){ cout << "Hello World!" << endl; }();
}

下面的例子和上面的一样,不过使用了auto关键字吧lambda表示先保存起来,然后再进行调用。

void test3()
{
	auto f = [](){ cout << "Hello World!" << endl; };
	f();
}

下面是一个稍微全面一点的例子,演示按值和按引用方式捕获变量的不同之处,同时还包含参数、返回值等使用方法。

void test4()
{
	int a = 0, b = 0;
	int c = [&, b] () mutable -> int { return (++a) + (++b); }();
	cout << a << " " << b << " " << c << endl; //输出:1 0 2
}

下面是一个说明lambda表达式和STL结合使用的简单例子。事实上,由于STL很多使用到仿函数的地方,所以把lambda和STL结合很多时候用起来非常方便。

void test5()
{
	//初始化
	int a[] = {1, 3, 2, 5, 4};
	vector<int> v(a, a + 5);
	// vector<int> v {1, 2, 3, 4, 5}; 统一初始化

	//非lambda版本输出
	for (auto p = v.begin(); p != v.end(); p++)
		cout << *p << " ";
	cout << endl; //输出:1 3 2 5 4

	//lambda版本倒序排序
	sort(v.begin(), v.end(), [](const int &a, const int &b) -> bool { return a > b; });

	//lambda版本遍历
	for_each(v.begin(), v.end(), [](int val){ cout << val << " "; });	
	cout << endl; //输出:5 4 3 2 1
}
上一篇: 下一篇:

我的博客

NoAlGo头像编程这件小事牵扯到太多的知识,很容易知其然而不知其所以然,但真正了不起的程序员对自己程序的每一个字节都了如指掌,要立足基础理论,努力提升自我的专业修养。

站内搜索

最新评论