Lambda表达式的范例
2016-04-20 20:59
375 查看
资料来源:https://msdn.microsoft.com/en-us/library/dd293599.aspx
本文介绍了如何在自己的程序中使用Lambda表达式。因为lambda表达式的概述,看到C++ Lambda表达式。关于一个lambda表达式结构的更多信息,参见lambda表达式的语法。
调用lambda表达式
嵌套lambda表达式
高阶lambda函数
在一个函数使用lambda表达式
使用带lambda表达式的模板
处理异常
使用lambda表达式与托管类型(C++ / CLI)
因为lambda表达式输入,你可以将它分配给一个自动变量或函数对象,如下所示:
C++编码:
5
7
备注:
更多信息,请参考(C++类,函数,和函数调用(C++))。
虽然lambda表达式通常是在一个函数体声明,你可以声明这些地方,你可以初始化一个变量。
例2:
当表达式被声明,而没有被调用时,Visual C++编译器绑定一个被捕获到的lambda表达式。下面的例子展示了一个lambda表达式捕获的局部变量i的值和局部变量j的引用。因为lambda表达式按值捕获到i,i在程序中再分配,不会影响表达式的结果。然而,因为lambda表达式按引用捕获到j的值,j在程序中再分配,就会影响到表达式的结果。
C++编码:
47
例1:
该示例声明了一个lambda表达式,通过传递两个参数4和5调用lambda表达式,返回两个数的和:
9
例2:
该示例通过传递一个lambda表达式作为find_if函数的参数,如果该参数是偶数的话,则返回TRUE:
The first even number in the list is 42.
注解:
关于find_if函数的更多信息,请参考find_if,关于更多STL函数的信息,请参考Algorithm
你可以像下面这个例子一样嵌套另外一个lambda表达式,内部lambda表达式乘以2并返回结果,外部lambda表达式通过它的参数调用内部lambda表达式并加上3返回结果:
代码:
13
注解:
在这个例子中,[](int y) { return y * 2; } 是一个内嵌的lambda表达式。
许多编程语言都支持高阶函数的概念。一个lambda表达式的高阶函数通过将另外一个lambda表达式作为一个参数进行调用,或者返回一个lambda表达式。你可以使用一个函数类来确保一个C++lambda表达式能够实现高阶函数功能。下面的例子显示一个lambda表达式返回一个函数对象,和一个lambda表达式作为一个函数对象的参数:
30
你可以在一个函数体内使用lambda表达式,这个lambda表达式可以访问和该函数相关的任何函数和数据成员,你可以显式或隐式捕获该指针以提供封闭类的功能和数据成员的访问。
你可以在一个函数中使用一个指针,如下所示:
3
6
9
12
注解:
ApplyScale函数使用一个lambda表达式去打印scale对象的值和一个vector对象的元素。该lambda表达式隐式地捕获到该指针以至于它可以访问_scale成员。
因为lambda表达式是一个类型,你可以使用一个带lambda表达式的C++模板。下面的例子显示了negate_all函数和print_all函数。 其中negate_all函数适用于一元操作符中的每个元素的矢量对象。print_all函数打印向量对象的每个元素到控制台界面:
代码:
34
-43
56
After negate_all():
-34
43
-56
注解:
要获得更多关于C++模板的信息,请查看Template (C++)。
Lambda表达式的主体内容为结构化异常处理规则(SEH)和C++异常处理。你可以处理lambda表达式中引发的异常或延迟异常处理的封闭范围。下面的例子使用了for_each函数和lambda表达式填充矢量对象与另一个值。它使用一个尝试/捕捉块来处理无效的访问第一个向量。
代码:
Caught 'invalid vector<T> subscript'.
注解:
要获得更多关于异常处理的信息,请参考Exception Handling in Visual C++ 。
一个lambda表达式不能包含变量的托管类型的捕获子句。然而,你可以通过参数有一个托管式Lambda表达式的参数列表。下面的示例包含一个lambda表达式捕获本地托管变量的值,以CH系统。字符串对象作为参数。
代码:
Hello!
注解:
你可以使用带有STL/CLR库的lambda表达式。为了获得更多信息,请参考:STL/CLR Library Reference。
本文介绍了如何在自己的程序中使用Lambda表达式。因为lambda表达式的概述,看到C++ Lambda表达式。关于一个lambda表达式结构的更多信息,参见lambda表达式的语法。
1、在这篇文章中
声明lambda表达式调用lambda表达式
嵌套lambda表达式
高阶lambda函数
在一个函数使用lambda表达式
使用带lambda表达式的模板
处理异常
使用lambda表达式与托管类型(C++ / CLI)
2、声明lambda表达式
例1:因为lambda表达式输入,你可以将它分配给一个自动变量或函数对象,如下所示:
C++编码:
// declaring_lambda_expressions1.cpp // compile with: /EHsc /W4 #include <functional> #include <iostream> int main() { using namespace std; // Assign the lambda expression that adds two numbers to an auto variable. auto f1 = [](int x, int y) { return x + y; }; cout << f1(2, 3) << endl; // Assign the same lambda expression to a function object. function<int(int, int)> f2 = [](int x, int y) { return x + y; }; cout << f2(3, 4) << endl; }输出结果:
5
7
备注:
更多信息,请参考(C++类,函数,和函数调用(C++))。
虽然lambda表达式通常是在一个函数体声明,你可以声明这些地方,你可以初始化一个变量。
例2:
当表达式被声明,而没有被调用时,Visual C++编译器绑定一个被捕获到的lambda表达式。下面的例子展示了一个lambda表达式捕获的局部变量i的值和局部变量j的引用。因为lambda表达式按值捕获到i,i在程序中再分配,不会影响表达式的结果。然而,因为lambda表达式按引用捕获到j的值,j在程序中再分配,就会影响到表达式的结果。
C++编码:
// declaring_lambda_expressions2.cpp // compile with: /EHsc /W4 #include <functional> #include <iostream> int main() { using namespace std; int i = 3; int j = 5; // The following lambda expression captures i by value and // j by reference. function<int (void)> f = [i, &j] { return i + j; }; // Change the values of i and j. i = 22; j = 44; // Call f and print its result. cout << f() << endl; }输出结果:
47
3、调用lambda表达式
你可以立即调用一个lambda表达式,如下面的代码所示。第二段代码显示了如何通过将lambda表达式作为一个参数实现标准模板库(STL)的调用。如find_if函数:例1:
该示例声明了一个lambda表达式,通过传递两个参数4和5调用lambda表达式,返回两个数的和:
// calling_lambda_expressions1.cpp // compile with: /EHsc #include <iostream> int main() { using namespace std; int n = [] (int x, int y) { return x + y; }(5, 4); cout << n << endl; }输出结果:
9
例2:
该示例通过传递一个lambda表达式作为find_if函数的参数,如果该参数是偶数的话,则返回TRUE:
// calling_lambda_expressions2.cpp // compile with: /EHsc /W4 #include <list> #include <algorithm> #include <iostream> int main() { using namespace std; // Create a list of integers with a few initial elements. list<int> numbers; numbers.push_back(13); numbers.push_back(17); numbers.push_back(42); numbers.push_back(46); numbers.push_back(99); // Use the find_if function and a lambda expression to find the // first even number in the list. const list<int>::const_iterator result = find_if(numbers.begin(), numbers.end(),[](int n) { return (n % 2) == 0; }); // Print the result. if (result != numbers.end()) { cout << "The first even number in the list is " << *result << "." << endl; } else { cout << "The list contains no even numbers." << endl; } }输出结果:
The first even number in the list is 42.
注解:
关于find_if函数的更多信息,请参考find_if,关于更多STL函数的信息,请参考Algorithm
4、嵌套lambda表达式
例子:你可以像下面这个例子一样嵌套另外一个lambda表达式,内部lambda表达式乘以2并返回结果,外部lambda表达式通过它的参数调用内部lambda表达式并加上3返回结果:
代码:
// nesting_lambda_expressions.cpp // compile with: /EHsc /W4 #include <iostream> int main() { using namespace std; // The following lambda expression contains a nested lambda // expression. int timestwoplusthree = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5); // Print the result. cout << timestwoplusthree << endl; }输出结果:
13
注解:
在这个例子中,[](int y) { return y * 2; } 是一个内嵌的lambda表达式。
5、高阶lambda函数
例子:许多编程语言都支持高阶函数的概念。一个lambda表达式的高阶函数通过将另外一个lambda表达式作为一个参数进行调用,或者返回一个lambda表达式。你可以使用一个函数类来确保一个C++lambda表达式能够实现高阶函数功能。下面的例子显示一个lambda表达式返回一个函数对象,和一个lambda表达式作为一个函数对象的参数:
// higher_order_lambda_expression.cpp // compile with: /EHsc /W4 #include <iostream> #include <functional> int main() { using namespace std; // The following code declares a lambda expression that returns // another lambda expression that adds two numbers. // The returned lambda expression captures parameter x by value. auto addtwointegers = [](int x) -> function<int(int)> { return [=](int y) { return x + y; }; }; // The following code declares a lambda expression that takes another // lambda expression as its argument. // The lambda expression applies the argument z to the function f // and multiplies by 2. auto higherorder = [](const function<int(int)>& f, int z) { return f(z) * 2; }; // Call the lambda expression that is bound to higherorder. auto answer = higherorder(addtwointegers(7), 8); // Print the result, which is (7+8)*2. cout << answer << endl; }输出结果:
30
6、在一个函数使用lambda表达式
例子:你可以在一个函数体内使用lambda表达式,这个lambda表达式可以访问和该函数相关的任何函数和数据成员,你可以显式或隐式捕获该指针以提供封闭类的功能和数据成员的访问。
你可以在一个函数中使用一个指针,如下所示:
void ApplyScale(const vector<int>& v) const { for_each(v.begin(), v.end(), [this](int n) { cout << n * _scale << endl; }); }你可以隐式地捕获该指针:
void ApplyScale(const vector<int>& v) const { for_each(v.begin(), v.end(), [=](int n) { cout << n * _scale << endl; }); <span style="font-size:14px;">}</span>下面的示例显示Scale类,它封装了一个scale值:
// function_lambda_expression.cpp // compile with: /EHsc /W4 #include <algorithm> #include <iostream> #include <vector> using namespace std; class Scale { public: // The constructor. explicit Scale(int scale) : _scale(scale) {} // Prints the product of each element in a vector object // and the scale value to the console. void ApplyScale(const vector<int>& v) const { for_each(v.begin(), v.end(), [=](int n) { cout << n * _scale << endl; }); } private: int _scale; }; int main() { vector<int> values; values.push_back(1); values.push_back(2); values.push_back(3); values.push_back(4); // Create a Scale object that scales elements by 3 and apply // it to the vector object. Does not modify the vector. Scale s(3); s.ApplyScale(values); }输出结果:
3
6
9
12
注解:
ApplyScale函数使用一个lambda表达式去打印scale对象的值和一个vector对象的元素。该lambda表达式隐式地捕获到该指针以至于它可以访问_scale成员。
7、使用带lambda表达式的模板
例子:因为lambda表达式是一个类型,你可以使用一个带lambda表达式的C++模板。下面的例子显示了negate_all函数和print_all函数。 其中negate_all函数适用于一元操作符中的每个元素的矢量对象。print_all函数打印向量对象的每个元素到控制台界面:
代码:
// template_lambda_expression.cpp // compile with: /EHsc #include <vector> #include <algorithm> #include <iostream> using namespace std; // Negates each element in the vector object. Assumes signed data type. template <typename T> void negate_all(vector<T>& v) { for_each(v.begin(), v.end(), [](T& n) { n = -n; }); } // Prints to the console each element in the vector object. template <typename T> void print_all(const vector<T>& v) { for_each(v.begin(), v.end(), [](const T& n) { cout << n << endl; }); } int main() { // Create a vector of signed integers with a few elements. vector<int> v; v.push_back(34); v.push_back(-43); v.push_back(56); print_all(v); negate_all(v); cout << "After negate_all():" << endl; print_all(v); }输出结果:
34
-43
56
After negate_all():
-34
43
-56
注解:
要获得更多关于C++模板的信息,请查看Template (C++)。
8、处理异常
例子:Lambda表达式的主体内容为结构化异常处理规则(SEH)和C++异常处理。你可以处理lambda表达式中引发的异常或延迟异常处理的封闭范围。下面的例子使用了for_each函数和lambda表达式填充矢量对象与另一个值。它使用一个尝试/捕捉块来处理无效的访问第一个向量。
代码:
// eh_lambda_expression.cpp // compile with: /EHsc /W4 #include <vector> #include <algorithm> #include <iostream> using namespace std; int main() { // Create a vector that contains 3 elements. vector<int> elements(3); // Create another vector that contains index values. vector<int> indices(3); indices[0] = 0; indices[1] = -1; // This is not a valid subscript. It will trigger an exception. indices[2] = 2; // Use the values from the vector of index values to // fill the elements vector. This example uses a // try/catch block to handle invalid access to the // elements vector. try { for_each(indices.begin(), indices.end(), [&](int index) { elements.at(index) = index; }); } catch (const out_of_range& e) { cerr << "Caught '" << e.what() << "'." << endl; }; }输出结果:
Caught 'invalid vector<T> subscript'.
注解:
要获得更多关于异常处理的信息,请参考Exception Handling in Visual C++ 。
9、使用代用托管类型的lambda表达式
例子:一个lambda表达式不能包含变量的托管类型的捕获子句。然而,你可以通过参数有一个托管式Lambda表达式的参数列表。下面的示例包含一个lambda表达式捕获本地托管变量的值,以CH系统。字符串对象作为参数。
代码:
// managed_lambda_expression.cpp // compile with: /clr using namespace System; int main() { char ch = '!'; // a local unmanaged variable // The following lambda expression captures local variables // by value and takes a managed String object as its parameter. [=](String ^s) { Console::WriteLine(s + Convert::ToChar(ch)); }("Hello"); }输出结果:
Hello!
注解:
你可以使用带有STL/CLR库的lambda表达式。为了获得更多信息,请参考:STL/CLR Library Reference。
相关文章推荐
- OpenCV学习笔记(六)—— OpenCV for Android打开相机
- app 启动原理
- 冲刺2
- 基于Netty的“请求-响应”同步通信机制实现
- python读取邮箱邮件数据并下载附件
- Android-Drozer的安装错误
- 分析问题和学习知识的方法论区别
- hdu 1878 欧拉回路
- POJ 3735 Training little cats(矩阵快速幂)
- LeetCode *** 131. Palindrome Partitioning
- android串口操作
- Oracle-SQL04
- POJ 3735 Training little cats(矩阵快速幂)
- CentOS 7.1安装Elasticsearch和Storm
- 私营太空,如何在宇宙中圈地?
- [bzoj4542][HNOI2016]大数
- POJ 2983 查分约束+SPFA
- sqlite线程模式
- 连连看(bfs ,优先队列搜索)
- 【一】——C++模板