C++ Lambda表达式 学习笔记

/*
     本篇主要讲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<int>& v) 
{
for_each(v.begin(), v.end(), [=](int n) { cout << m_nValue * n << endl; });
}


private:
int m_nValue;
};


void  Test_Lambda() 
{
vector<int> 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<int> vec(10);
generate(vec.begin(), vec.end(), [] { return nextValue++; });
for_each(vec.begin(), vec.end(), [](int n) { cout << n << endl; });
}




namespace Lambda_1 
{
template <typename C> 
void print(const string& s, const C& c) 
{
cout << s;
for (const auto& e : c) {
cout << e << " ";
}
cout << endl;
}


void fillVector(vector<int>& v) 
{
static int nextValue(0);
generate(v.begin(), v.end(), [] { return nextValue++; });
}


void  Func() 
{
const int elementCount = 9;
vector<int> 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<int(int, int)> 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<int(void)> 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<int>  v;
v.push_back(17);
v.push_back(21);
v.push_back(8);
v.push_back(15);
v.push_back(91);


vector<int>::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<int(int)> 
{
return [=](int y) { return x + y; };
};


auto higerorder = [](const function<int(int)>& 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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值