C++第十四章:lambda ,->箭头运算的重载,function 模板

lambda表达式用法

C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。Lambda 表达式本质上与函数声明非常类似。

首先看一些基本的lambda表达
#一
[capture](parameters)->return-type{body}
 
//例如
[](int x, int y) -> int { int z = x + y; return z + x; }
int main(){
  int a = 1;
  int b = 2;
  auto lambda = []{return a + b;}; 
  //error! 空捕获列表,无法使用作用域内其他变量
  
  auto lambda = [](int a, int b){return a + b;}; 
  //success
 
  auto lambda = [=]{return a + b;}; 
  //success, 值传递
 
  auto lambda = [=]{a++; b++; return a + b;}; 
  //error! 值传递无法修改变量值 因为根据合成的类该调用运算符是const成员函数,
  //在const成员函数中,不能有修改数据的操作,会报错。
  //不可修改a,b,如果需要修改则在(参数)后添加限定符mutable
  
  size_t v1 = 42;
  auto lambda = [=]()mutable{return ++v1}; 
  //一般lambda值传递无法修改拷贝的变量,但加上关键词mutable便可变了,相当于去掉const不是const成员函数


  auto lambda = [&]{a++; b++; return a + b;}; 
  //success, 引用传递
 
  auto lambda = [&a, b]{a++; b++; return a + b;}; 
  //error, 变量a引用传递,变量b值传递,故b不可修改
  
  auto lambda = [this]{a++; b++; return a + b;}; 
 [this]表示值传递方式捕捉当前的this指针
}
#二
[capture](parameters)->return-type{body}
//混合隐式和显式捕获,首先第一个元素必须一个是&或者=,且第二个显示捕获的变量必须与隐式不同的方式
[&, c]{ return cout <<c;}//正确:方式不同,第一个引用捕获,第二个值捕获
[&, &c]{ return cout <<c;}//错误,方式一样
[=, &c]{ return cout <<c;}//正确:方式不同,第一个值捕获,第二个引用捕获
[=, c]{ return cout <<c;}//错误,方式一样


指定lambda返回类型:C++14 或C++17修改了限制,return中还有其他语句时可以判断返回类型了,并不需要指定返回类型。

#三:
transform(vi.begin(), vi.end(), vi.begin(), [](int i)
 {if (i < 0) return -i; else return i; });
//实际上当一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数
//旧是此编译器生成的类类型的未命名对象,类似的,使用auto定义一个用lambda初始化的变量时

//定义了一个从lambda生成的类型的对象
//类中含有一个重载的函数调用运算符
以下:
stable_sort(word.begin(), word.end(), [](const string&a, const string &b) 
{return a.size() < b.size(); });

//行为类似于下面这个类的一个未命名对象
class ShorterString
{
public:
bool operator()(const string&s1, const string &s2)const
{return s1.size() < s2.size();}
}

//则可以用这个类替代lambda表达式替代,重写,当stable_sort的内部代码每次比较两个string
//时就会“调用”这一对象,此时该对象将调用运算符的函数体进行判断是否返回ture
stable_sort(word.begin(), word.end(), ShorterString())


#如果含有捕获参数,是值传递的参数则合成的类中有该参数的数据成员,用捕获的量来初始化来该成员
#如果是引用则不需要:类似以下
auto wc= find_if(words.begin(),words.end(),[sz](const string&a){return a.size()<=sz})
//捕获的sz以值传递的方式获得,拷贝到n再去初始化类中的sz
class ShorterString
{
public:
ShorterString(int n):sz(n){};
bool operator()(const string&s1)const
{return s1.size() < sz;}
privata:
size_t sz;
}
lambda产生的类不含默认构造函数,赋值运算符及默认析构函数,如果有值传递参数,则需要提供实参的构造函数
其他拷贝/移动构造函数则通常要根据捕获的数据成员类型而定

箭头运算符:

在这里插入代码片

function模板:

function 能表示共享同一种调用形式,尽管他们的类型是不相同的,function能包含所有的可调用对象。以下:

	class PFH
	{
	public:
		int operator()(int i, int j)
		{
	
			return i*i + j*j;
	
		}
	};
	int  a_dd(int i, int j)
	{
		return i + j;
	}
	int divi_des(int i, int j)
	{
	
		return i / j;
	}
	map <string, function<int(int, int)>> binops =
	{
		{"+",add},//函数指针
		{"-",std::minus<int>()},//标准库函数
		{"/",divi_des} ,// 自定义函数
		{"*",[](int i, int j) {return i * j; }} ,//未命名的lambda
		{"%" ,mod},//命名的lmabda
		{"_2",PFH()}//自定义的函数对象
	};
	cout << binops["+"](5, 2) <<endl;
	cout << binops["-"](5, 2) << endl;
	cout << binops["/"](5, 2) << endl;
	cout << binops["*"](5, 2) << endl;
	cout << binops["%"](5, 2) << endl;
	cout << binops["_2"](5, 2) << endl;
	但如果有重载函数,用函数指针或lambda来消除二义性
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lambda表达式->,是Java 8中引入的一种函数式编程的特性。它可以简洁地表示一个匿名函数,可以作为参数传递给方法或函数。Lambda表达式的结构可以根据需要有零个或多个参数,参数可以明确声明或根据上下文推断。参数需包含在圆括号内,参数之间用逗号相隔。当只有一个参数且其类型可推导时,圆括号可以省略。Lambda表达式的主体可以包含零条或多条语句,如果主体只有一条语句,花括号{}可以省略。Lambda表达式的返回类型与主体表达式一致。如果主体包含一条以上的语句,表达式必须包含在花括号{}中形成代码块,返回类型与代码块的返回类型一致。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Lambda 表达式](https://blog.csdn.net/xxdw1992/article/details/103903210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [深入浅出 Java 8 Lambda 表达式](https://blog.csdn.net/u012910595/article/details/70833510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值