C++11Lanbda表达式(匿名函数)

目录

介绍Lambad表达式

用例说明

值传递

当我尝试修改值传递进去的值时就会报错。

​编辑

引用传递(可读可写)

 mutable关键字

有返回值

实战小例子

 使用lambda表达式遍历数据

使用仿函数求数组的和


介绍Lambad表达式

C++11中引入了Lambda表达式 用于定义并创建匿名函数对象,以简化编程工作。

首先我们了解一下Lambda表达式的格式:

[函数对象参数](操作符重载函数参数)mutable->返回值类型{函数体}

[capture](parameters)mutable->return-type
{
    statement;
}
  1. 函数对象参数(也叫捕获列表):[]标识一个Lambda的开始,不可省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些定义Lambda为止时且在Lambda所在作用范围内可见的局部变量和所在类的this。函数对象参数有下面几种:
    1. [] 空的,就是无法访问作用域外的。
    2. [=] 等号运算符。表示函数体内可以使用Lambda所在作用范围内且所有可见的局部变量和所在类的this,而且是值传递方式
    3. [&] 取地址运算符。表示函数体内可以使用Lambda所在作用范围内且所有可见的局部变量和所在类的this,而且是引用传递方式
    4. this。函数体内可以使用Lambda所在类中的成员变量。
    5. a。将a按值进行传递。按值传递时,函数体内不能修改传递进来变量的值,因为默认情况下函数是const的。要修改传递进来的值,需要添加mutable关键字。
    6. &a。将a按照引用传递。

     

     

     

  2. 操作符重载函数参数:表示重载的()操作符的参数,没有参数时,这部分可以省略。参数可以按值和按引用俩种方式进行传参。
  3. 可修改标识符:mutable声明,这部分可以省略。按值传递时,加上mutable修饰符后就可以修改传进来的拷贝变量。
  4. 函数返回值:->返回值类型。表示函数返回值类型,当返回值为void,或者函数体中只有一处return的地址时,这部分可以省略。因为只有一处return时编译器可以自动推测出返回值类型。
  5. 函数体:{} 函数实现的位置。这部分不可省略。当函数体可以为空。

用例说明

值传递

最后加个()就是函数调用。不加的话只是个函数声明。

int main()
{
	// 最后加个()就是函数调用
	[=](int i)
	{
		cout << "LinXi" << i << endl;
	}(3);
	return 0;
}
int main()
{
	// 最后加个()就是函数调用
	int x = 23;
	[x]()
	{
		cout << "LinXi" << x << endl;
	}();
	cout << x << endl;
	return 0;
}

当我尝试修改值传递进去的值时就会报错。

 

引用传递(可读可写)

函数里面修改,外部的x值就会改变。

int main()
{
	// 最后加个()就是函数调用
	int x = 23;
	[&](int& i)
	{
		cout << "LinXi" << ++i << endl;
	}(x);
	cout << x << endl;
	return 0;
}
int main()
{
	// 最后加个()就是函数调用
	int x = 23;
	[&x]()
	{
		cout << "LinXi" << ++x << endl;
	}();
	cout << x << endl;
	return 0;
}

运行结果图:

 mutable关键字

int main()
{
	// 最后加个()就是函数调用
	int x = 23;
	[x]()mutable
	{
		cout << "LinXi" << ++x << endl;
	}();
	cout << x << endl;
	return 0;
}

可以看到在函数内部对x的值进行了修改 ,但是外面x的值依然没变。

有返回值

int main()
{
	// 最后加个()就是函数调用
	const int ret = []()->int { return 1024; }();
	cout << ret << endl;
	return 0;
}

对比下面俩张图可以看到省略掉返回值类型程序也能正常返回。证明编译器可以自动推测出返回值类型。

实战小例子

 使用lambda表达式遍历数据

template<class T, class T2>
void For_each(const T* arr, int cnt, T2 t2)
{
    for (auto i = 0; i < cnt; ++i)
    {
        t2(arr[i]);
    }
}
int main()
{
    int arr[] = { 9,6,5,2,3,1,4,7 };
    int*p = arr;
    For_each(p, sizeof(arr) / sizeof(arr[0]), [&](const int& num)
    {
        cout << num << " ";
    });
    cout << endl;
    return 0;
}

使用仿函数求数组的和

struct Sum //仿函数
{
private:
    int total = 0;
public:
    void operator()(int val)
    {
        total += val;
    }
    void output() const
    {
        cout << "total = " << total << endl;
    }
};

template<class T, class T2>
T2 For_each(const T* arr, int cnt, T2 t2)
{
    for (int i = 0; i < cnt; ++i)
    {
        t2(arr[i]);
    }
    return t2;
}
 
int main()
{
    int arr[] = { 6,5,3,2,1,9,8,74 };
    Sum sum = For_each(arr, 8, Sum());
    sum.output();
    return 0;
}
 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林夕07

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值