/*
本篇主要讲c++ 11标准的lambda表达式
时间:2017/06/05
*/
#include "iostream"
#include "algorithm"
#include "vector"
#include "string"
#include "functional"
using namespace std;
// lambda 表达式定义 是一个匿名函数,能够捕获上下文中出现的变量;
// lambda 表达式的各个部分;
// [=]() mutable throw() -> ret
// {
// }
// 1 capture 子句, 捕获列表, 是一个lambda表达式开始的地方
// 表明能够访问那些外部变量和以何种方式访问这些变量;
/*
* lambda可以通过参数列表引入新的变量;也可以捕获上下文中的变量;
* 也可以通过capture子句指定捕获的方式是传值的方式还是引用的方式;
* [] 表示lambda主体中不访问上下文中的任何变量;
*
* [&] 表示以引用的方式捕获所有的变量;
* [=] 表示以值的方式捕获所有的变量;
* [&x, y] 表示以引用的方式捕获外部变量x, 以值的方式捕获外部变量y
* [&, x] 表示以引用方式捕获所有变量,除了x
* [x, &] -->>> error 前面说了以值的方式捕获x,后面又说以引用捕获所有变量
* [=, &x] 表示以值的方式捕获所有变量,除了x
* [&x, =] -->>> error
*
* [&, &x] --->>> 语意重复 error
* [=, this]
* [i, i]
* [this] 表示捕获当前类的this指针,可以使用当前类的成员变量和函数
*
* 可以在捕获列表中引入并初始化变量
*/
// 2 参数列表, 相当于函数参数列表, 可选项
/*
* lambda 申明符, 类似于函数的参数
*
*
*/
// 3 可变规范 可选项
/*
* mutable表明lambda函数主体可以修改外部捕获的变量的副本,可以调用捕获对象的非const方法
* exception表明lambda表达式的异常处理
* attribute
*/
// 4 异常规范
/*
*
*
*/
// 5 返回类型
/*
* lambda 表达式的返回类型 可选项
*
*/
// 6 lambda表达式的函数主体
/*
* lambda表达式的函数主体
*
*/
class Lambda
{
public:
Lambda(int nValue)
: m_nValue(nValue)
{
}
void Func(int i)
{
[&, i] { };
[this] { return m_nValue; };
//
[&, &i] { }; error &包含了以引用的捕获方式
//
[=, this] { return m_nValue; } error =包含了以值的捕获方式
}
void Func1(const vector& v)
{
for_each(v.begin(), v.end(), [=](int n) { cout << m_nValue * n << endl; });
}
private:
int m_nValue;
};
void Test_Lambda()
{
vector v;
for (int i = 1; i < 5; ++i) {
v.push_back(i);
}
Lambda lambda(4);
lambda.Func1(v);
}
// 引用捕获会修改外部变量;值捕获不会修改外部变量;
// mutable允许捕获的副本进行修改,但原件不会;
void Test_Lambda_0()
{
int i = 10;
int j = 100;
// cout << "i = " << i << " j = " << j << endl;
auto func = [&i, j](int n) { i = i + n; cout << "j = " << j << endl; };
func(20);
// cout << "i = " << i << " j = " << j << endl;
auto func1 = [&i, j](int n) mutable { i = i + n; j = j + n; };
func1(20);
// cout << "i = " << i << " j = " << j << endl;
}
// 异常规范
void Test_Lambda_1()
{
[]() throw() { throw 0; }();
}
// 返回类型
// lambda 表达式的返回类型是可以自动推导的;
// 可以省略 return type部分;如果lambda表达式只包含一个 返回语句或者没有返回的时候;
// 如果你指定了 return type, 则需要加上关键字 ->
void Test_Lambda_2()
{
//
auto x1 = [](int i) ->int { return i; };
auto x1 = [](int i) { return i; };
cout << x1(100) << endl;
//
auto x2 = [] { return {1, 2}; }; error
}
// 函数主体
void Test_Lambda_3()
{
int m = 0;
int n = 0;
[&, n](int a) mutable { m = ++n + a; }(5);
cout << m << " " << n << endl;
}
//
void Test_Lamdba_4()
{
static int nextValue(0);
vector vec(10);
generate(vec.begin(), vec.end(), [] { return nextValue++; });
for_each(vec.begin(), vec.end(), [](int n) { cout << n << endl; });
}
namespace Lambda_1
{
template
void print(const string& s, const C& c)
{
cout << s;
for (const auto& e : c) {
cout << e << " ";
}
cout << endl;
}
void fillVector(vector& v)
{
static int nextValue(0);
generate(v.begin(), v.end(), [] { return nextValue++; });
}
void Func()
{
const int elementCount = 9;
vector v(elementCount, 1);
int x = 1;
int y = 1;
generate_n(v.begin() + 2,
elementCount - 2,
[=]() mutable throw() -> int {
// cout << x << y << endl;
cout << "x = " << x << " y = " << y << endl;
int n = x + y;
x = y;
y = n;
return n;
});
print("vector v after call to generate_n() with lambda: ", v);
cout << " x = " << x << " y = " << y << endl;
fillVector(v);
print("vector v after 1st call to fillVector(): ", v);
}
}
// generate
// generate_n
void Test_Lambda_5()
{
int x = 1;
int y = 1;
auto func = [=]() mutable throw() -> int {
//
cout << "x = " << x << " y = " << y << endl;
int n = x + y;
++x;
++y;
return n;
};
for (int i = 0; i < 10; ++i) {
func();
}
}
/
// lambda 申明
/ 可以将lambda赋值auto变量或者 function对象
void Test_Lambda_6()
{
auto func1 = [](int x, int y) { return x + y; };
cout << func1(10, 20) << endl;
function func2 = [](int x, int y) { return x + y; };
cout << func2(10, 20) << endl;
}
// auto 是一个类型对象,可以用来表示任意的类型
// function 是函数对象封装,用来封装各种不同的函数对象;
// 如普通的函数,函数指针,lambda,类的方法,和静态方法,以及其他一些可调用的对象;
// lambda表达式绑定捕获的变量是在lambda表达式申明的时候
void Test_Lambda_7()
{
int i = 11;
int j = 22;
function func1 = [i, &j] { return i + j; }; // 绑定捕获列表
i = 40;
j = 50;
cout << func1() << endl; // 61
}
// lambda 表达式的调用
// 可以在申明的时候立即调用;
// 也可以作为stl算法的参数;
void Test_Lambda_8()
{
int n = [](int x, int y) { return x + y; }(5, 4);
cout << n << endl;
}
//
void Test_Lambda_9()
{
vector v;
v.push_back(17);
v.push_back(21);
v.push_back(8);
v.push_back(15);
v.push_back(91);
vector::iterator iter = find_if(v.begin(), v.end(),
[](int n) {
return n % 2 == 0;
});
if (iter != v.end()) {
cout << *iter << endl;
}
else {
cout << "not found even!" << endl;
}
}
// 嵌套的lambda表达式
void Test_Lambda_10()
{
int n = [](int x) { return [](int y) { return 2 * y; }(x) + 3; }(5);
cout << n << endl;
}
// 高阶lambda函数
// 高阶函数是将lambda表达式作为函数的参数或者作为返回值类型
// 使用function对象
void Test_Lambda_11()
{
auto func = [](int x) ->function
{
return [=](int y) { return x + y; };
};
auto higerorder = [](const function& f, int z)
{
return 2 * f(z);
};
auto answer = higerorder(func(7), 8);
cout << answer << endl;
}
int main()
{
// Test_Lambda();
// Test_Lambda_0();
// Test_Lambda_1();
// Test_Lambda_2();
// Test_Lambda_3();
// Test_Lamdba_4();
// Lambda_1::Func();
// Test_Lambda_5();
// Test_Lambda_6();
// Test_Lambda_7();
// Test_Lambda_8();
// Test_Lambda_9();
// Test_Lambda_10();
system("pause");
return 0;
}