栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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
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
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;
}
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030386.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号