C++11系列学习之二-----lambda表达式
2015-09-06 13:17
585 查看
C++11添加了一项名为lambda表达式的新功能,通过这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象,使得代码更容易理解。
lambda表达式的语法如下所示:
[capture_block](parameters) exceptions_specification -> return_type {body}
[捕捉块](参数) 异常 -> 返回值类型 {主体}
或者更直白地看如下:
这里假设我们定义了一个如上图的lambda表达式。现在来介绍途中标有编号的各个部分是什么意思。
1. Lambda表达式的引入标志,在‘[]’里面可以填入‘=’或‘&’表示该lambda表达式“捕获”(lambda表达式在一定的scope可以访问的数据)的数据时以什么方式捕获的,‘&’表示一引用的方式;‘=’表明以值传递的方式捕获,除非专门指出。
2. Lambda表达式的参数列表
3. Mutable 标识
4. 异常标识
5. 返回值类型
6.“函数”体,也就是lambda表达式需要进行的实际操作
下面的例子将逐步演示如何使用lambda表达式:
范例一:无参数的lambda表达式
or
输出如下所示:
Hello from Lambda
在控制台输出Hello from Lambda,尾部的括号使该表达式可立即执行。
范例二:带参数的lambda表达式
输出如下所示:
Hello from second Lambda
该lambda表达式接受一个string参数并返回一个string,结果保存在变量result中,尾部的括号使得该表达式立即执行。
范例三:像平常的调用函数一样使用lamdba表达式
输出如下所示:
hello from third lambda
此处保存指向lambda表达式的指针,并且通过函数指针执行该表达式。
范例四:(STL与lambda)
输出如下所示:
Found 6 values > 3
通过count_if算法计算vector中满足特定条件的元素个数,lambda表达式的形式给出了条件,注意表达式中的=,等号表示通过值捕捉所在作用域的变量,这个例子中捕捉的是value的值。前面的例子[]为空,即捕捉块为空,那么在lambda表达式的主体body内就无法访问变量了。以下是关于捕捉块的详细介绍:
[=] 通过值捕捉所有变量
[&] 通过引用捕捉所有变量
[value] 通过值捕捉value,不捕捉其它变量
[&value] 通过引用捕捉value,不捕捉其它变量
[=, &value] 默认通过值捕捉,变量value例外,通过引用捕捉
[&, value] 默认通过引用捕捉,变量value例外,通过值捕捉
范例五:(STL与lambda结合)
注意:这里必须使用[&index],而不能使用[index],原因在于index++;否则会出现
错误提示:不能在非可变 lambda 中修改按值捕获
通过for_each算法可以对给定范围中的所有元素执行特定操作,调用lambda表达式,并将这个值作为参数传递给lambda表达式。
范例六:(多个参数)
从以上示例来看,
1.如果我们想要提示返回的类型,就要加上->return_type {},否则,直接使用{}即可。
2.C++ 11的lamdba表达式来源于其它语言,像Python,也有lamdba表达式。如:lambda x: x * x
范例程序差不多了,在C++11中,官方似乎一直鼓励大家用lambda表达式,而不是函数对象,lambda表达式更易于使用和理解。
lambda表达式的语法如下所示:
[capture_block](parameters) exceptions_specification -> return_type {body}
[捕捉块](参数) 异常 -> 返回值类型 {主体}
或者更直白地看如下:
这里假设我们定义了一个如上图的lambda表达式。现在来介绍途中标有编号的各个部分是什么意思。
1. Lambda表达式的引入标志,在‘[]’里面可以填入‘=’或‘&’表示该lambda表达式“捕获”(lambda表达式在一定的scope可以访问的数据)的数据时以什么方式捕获的,‘&’表示一引用的方式;‘=’表明以值传递的方式捕获,除非专门指出。
2. Lambda表达式的参数列表
3. Mutable 标识
4. 异常标识
5. 返回值类型
6.“函数”体,也就是lambda表达式需要进行的实际操作
下面的例子将逐步演示如何使用lambda表达式:
范例一:无参数的lambda表达式
[]{std::cout<<"Hello from Lambda!"<<std::endl;}();
or
[](){std::cout << "Hello from Lambda!" << std::endl; }();
输出如下所示:
Hello from Lambda
在控制台输出Hello from Lambda,尾部的括号使该表达式可立即执行。
范例二:带参数的lambda表达式
string str = [](const string& str)->string{return "Hello from " + str; }("second lambda"); cout << str << endl;
输出如下所示:
Hello from second Lambda
该lambda表达式接受一个string参数并返回一个string,结果保存在变量result中,尾部的括号使得该表达式立即执行。
范例三:像平常的调用函数一样使用lamdba表达式
auto f = [](std::string str)->string{return "hello from " + str; }; auto f2 = [](std::string str) {return "hello from " + str; }; cout << f2("third lambda") << endl;
输出如下所示:
hello from third lambda
此处保存指向lambda表达式的指针,并且通过函数指针执行该表达式。
范例四:(STL与lambda)
#include <iostream> #include <algorithm> #include <vector> auto main(int argc, char** argv) -> int { std::vector<int> vec={1, 2, 3, 4, 5, 6, 7, 8, 9}; int value=3; int cnt=std::count_if(vec.cbegin(), vec.cend(), [=](int i){return i>value;}); std::cout<<"Found "<<cnt<<" values > "<<value<<std::endl; return 0; }
输出如下所示:
Found 6 values > 3
通过count_if算法计算vector中满足特定条件的元素个数,lambda表达式的形式给出了条件,注意表达式中的=,等号表示通过值捕捉所在作用域的变量,这个例子中捕捉的是value的值。前面的例子[]为空,即捕捉块为空,那么在lambda表达式的主体body内就无法访问变量了。以下是关于捕捉块的详细介绍:
[=] 通过值捕捉所有变量
[&] 通过引用捕捉所有变量
[value] 通过值捕捉value,不捕捉其它变量
[&value] 通过引用捕捉value,不捕捉其它变量
[=, &value] 默认通过值捕捉,变量value例外,通过引用捕捉
[&, value] 默认通过引用捕捉,变量value例外,通过值捕捉
范例五:(STL与lambda结合)
#include <iostream> #include <algorithm> #include <vector> auto main(int argc, char** argv) -> int { std::vector<int> vec2 = { 11, 22, 33, 44 }; int index = 0; for_each(vec2.begin(), vec2.end(), [index](int i){std::cout << "Value " << (index++) << ": " << i << std::endl; }); return 0; }
注意:这里必须使用[&index],而不能使用[index],原因在于index++;否则会出现
错误提示:不能在非可变 lambda 中修改按值捕获
通过for_each算法可以对给定范围中的所有元素执行特定操作,调用lambda表达式,并将这个值作为参数传递给lambda表达式。
范例六:(多个参数)
int n = [](int x, int y) { return x + y; }(5, 4); cout << n << endl;
从以上示例来看,
1.如果我们想要提示返回的类型,就要加上->return_type {},否则,直接使用{}即可。
2.C++ 11的lamdba表达式来源于其它语言,像Python,也有lamdba表达式。如:lambda x: x * x
范例程序差不多了,在C++11中,官方似乎一直鼓励大家用lambda表达式,而不是函数对象,lambda表达式更易于使用和理解。
相关文章推荐
- C++的第一步:Visual Studio 6.0~2013 各版本编译器下载汇总
- C/C++实现动态数组
- 指针与C++的基本原理
- Effective C++——条款24(第4章)
- C语言中send()函数和sendto()函数的使用方法
- C++中的多态性
- C++_运算符重载的注意事项
- C语言结构体中字符数组的问题
- C语言实现将字符串“askdaskaskdaskg”删除制定字符“ask”
- c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法儿
- 最长连续序列
- 【more effective c++读书笔记】【第5章】技术(5)——Reference counting(引用计数)(1)
- 【more effective c++读书笔记】【第5章】技术(5)——Reference counting(引用计数)(1)
- C++primer阅读笔记-模板与泛型编程(模板实参推断)
- C语言实现回文判断(利用指针的方法)
- c++ char* char*&的区别
- C语言:文件操作
- C++三大继承构造函数的执行顺序详解
- C++要掌握的知识点
- 在VS2008环境下的C++异常处理