泛型算法的定制操作多种实现方式 以find_if举例

泛型算法的定制操作多种实现方式

sort 要求第三个参数为 二元谓词

	//比较函数
	bool isShorter(const string &s1, const string &s2)
	{
		return s1.size() < s2.size();
	}
	//测试vector
	vector<string> strVec = {"cc","abc","hjg","das","dfgsdsd","abc","aa","cc","b","a","hjg" };
	//用<进行比较  结果参照string使用<进行比较的结果
	sort(strVec.begin(), strVec.end());
	//传入比较函数作为谓词  因为sort接受二元谓词,所以比较函数也得是两个参
	//将vec按照从短到长排序
	sort(strVec.begin(), strVec.end(), isShorter);
	//使用lamda表达式
	//同上
	sort(strVec.begin(), strVec.end(), [](const string &s1, const string &s2) {return s1.size() < s2.size(); });

find_if 要求第三个参数为一元谓词

//一个形参  可以作为一元谓词传给find_if
bool islonger1(const string &s1)
{
	return s1.size() > 2;
}
//两个形参  不可以传给find_if
bool islonger2(const string &s1,size_t sz)
{
	return s1.size() > sz;
}

//测试数据依然使用上面sort的内容
	size_t sz = 2;
//不用在意重定义,只是突出介绍方式

	//如果你想找到第一个长度为3的string,可以继续使用这种方式
	//但3已经被硬编码进函数,需求改变就只能再写不同的判断函数
	auto wc = find_if(strVec.begin(), ve.end(), islonger1);
	//这个时候 咱们的lambda表达式就排上用场的
	//捕获列表我自己捕获一个,实际参数还是只有1个
	//mutable->bool 这个可以忽略,写在这里是因为后面要介绍lambda原理
	auto wc = find_if(strVec.begin(), strVec.end(), [sz](const string &s1)mutable->bool {return s1.size() > sz; });
	//参数绑定 std::bind
	//可以理解为它为islonger2套了层壳
	//感兴趣的可以自己查阅一下资料
	auto wc = find_if(strVec.begin(), ve.end(), bind(islonger2, std::placeholders::_1,sz));
	//--------------------------
	class A
	{

		public:
			A(size_t a) :pa(a) {}
			bool operator ()(string x)
			{
				return x.size() > pa;
			}

		private:
			const size_t pa;

	};
	//这种方法就比较秀了 如果对于这种操作比较困惑,咱们得去看find_if的源码
	auto wc = find_if(strVec.begin(), strVec.end(),A(sz));

find_if源码

		// FUNCTION TEMPLATE find_if
template<class _InIt,
	class _Pr>
	_NODISCARD inline _InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred)
	{	// find first satisfying _Pred
	_Adl_verify_range(_First, _Last);
	auto _UFirst = _Get_unwrapped(_First);
	const auto _ULast = _Get_unwrapped(_Last);
	for (; _UFirst != _ULast; ++_UFirst)
		{
		//看到没有  上面最后一种方式 创建的临时对象调用被你重载的()运算符
		//刚好得到了find_if的条件判断
		//也解释了为什么find_if只能接受一个参数的比较函数
		//这里如果传入islonger1   就变成了  islonger1(*_UFirst)
		if (_Pred(*_UFirst))
			{
			break;
			}
		}

	_Seek_wrapped(_First, _UFirst);
	return (_First);
	}

总结:
三种方式来使原本只能接受一元谓词的函数处理多个入参

  1. lambda表达式
  2. std:bind
  3. 定义一个类,重载其()运算符,类成员在构造的时候变为额外入参

而且从源码上面可以得知,第二种和正常传入比较函数是同一种方式(普通函数调用),而第三种方式则是使用类重载运算符实现(也是调用函数,但使用的是类成员函数).

那么lambda是怎么办到的呢? mutable这个关键词是不是有种似曾相识,感觉在哪里见过?
后面有机会再写

c++中的lambda究竟是什么?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值