C++11——仿函数原理及使用场景

系列文章目录

C++11新特性大全+实例


前言

C++ 这门编程语言的历史可以追溯至 1979 年,当时的 Bjarne Stroustrup(C++ 之父,后续简称 Stroustrup)还在使用 Simula 语言进行开发工作。

1998 年,C++ 标准委员会发布了第一版 C++ 标准,并将其命名为 C++ 98 标准。据不知名人士透露,《带注释的C++参考手册》这本书对 C++ 98 标准的制定产生了很大的影响。

经过作者的不断迭代,一本书往往会先后发布很多个版本,其中每个新版本都是对前一个版本的修正和更新。C++ 编程语言的发展也是如此。截止到目前(2020 年),C++ 的发展历经了以下 3 个个标准:

2011 年,新的 C++ 11 标准诞生,用于取代 C++ 98 标准。

2014 年,C++ 14 标准发布,该标准库对 C++ 11 标准库做了更优的修改和更新;

2017 年底,C++ 17 标准正式颁布;

虽然学习 C++11 需要花些时间,但这是非常值得的;C++11 非常实用,它不但提高了开发效率,还让程序更加健壮和优雅。程序员应该乐于升级换代已有的知识,而学习和使用 C++11 早就是大势所趋。

|版本声明:山河君,未经博主允许,禁止转载

一、仿函数

1.定义

百度词条中给出定义:

仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。

C++STL其中包含4个组件,分别为算法、容器、函数、迭代器。而仿函数就是分在函数中用于模板类和模板函数中。

2.特点

其实定义中已经说明特点,这里单独进行强调一下:

1.仿函数不是函数是类

2.仿函数重载了()运算符,拥有函数的行为

二、仿函数使用

1.基本使用

首先看一下基本上都知道的算法函数for_each遍历容器,打印所有的数值

void fun(int i)
{
	cout << i << endl;
}

int main(int argv, char* argc[])
{
	vector<int> it = { 1,2,3,4, 6, 7, 8 };
	for_each(it.begin(), it.end(), fun);

	return 0;
}

如果是用仿函数,这个时候实际会创建一个临时的print对象,然后调用()方法

class print {
public:
	print()
	{
		cout << "This is print" << endl;
	}
public:
	void operator()(int i)
	{
		cout << i << endl;
	}
};

int main(int argv, char* argc[])
{
	vector<int> it = { 1,2,3,4, 6, 7, 8 };
	for_each(it.begin(), it.end(), print());
	return 0;
}

输出结果:
在这里插入图片描述
不过这样看起来还不如不用仿函数,那么我们看下面一个例子

2.要求打出小于5的值

还是上面那个例子,不过现在新增要求,打印小于5的数值,这时候发现sor不容易传入接口

void fun(int i, int j)
{
	if(i < j)
		cout << i << endl;
}

这时,实际上有两种方法可以解决问题

1.利用bind绑定,这种用法请查看C++11特性bind,这里不做介绍

void fun(int i, int j)
{
	if (i < j)
		cout << i << endl;
}
int main(int argv, char* argc[])
{
	vector<int> it = { 1,2,3,4, 6, 7, 8 };
	for_each(it.begin(), it.end(), std::bind(fun, std::placeholders::_1, 5));
	return 0;
}

2.利用仿函数

class print {
public:
	print(int j) : m_j(j)
	{
		cout << "This is print" << endl;
	}
public:
	void operator()(int i)
	{
		if(i < m_j)
			cout << i << endl;
	}

public:
	int m_j;
};


int main(int argv, char* argc[])
{
	vector<int> it = { 1,2,3,4, 6, 7, 8 };
	for_each(it.begin(), it.end(), print(5));
	return 0;
}

3.结合模板使用

看到这里可能会说,仿函数一方面必须要在类里实现operator,一方面还可以被更简便的方法替代,那么为什么还要使用仿函数?

其实上文已经说了,仿函数是配合STL进行使用,用于方便模板类和模板函数。

还是上面那个例子,但是现在不确定vector存储的类型,也不确定所输出的条件

class print {
public:
	print(T j) : m_j(j) //模板类,不确定条件类型
	{
		cout << "This is print" << endl;
	}
public:
	void operator()(int i) //输出比j小的值
	{
		if(i < m_j)
			cout << i << endl;
	}


	void operator()(string i) //打印字符串大小小于j的值
	{
		if (i.size() < m_j)
			cout << i << endl;
	}

	void operator()(double i) //打印double比i小的值
	{
		if (i < m_j)
			cout << i << endl;
	}

public:
	T m_j;
};


int main(int argv, char* argc[])
{
	vector<int> it1 = { 1,2,3,4, 6, 7, 8 };
	for_each(it1.begin(), it1.end(), print(5));

	vector<string> it2 = { "123", "12345", "123436", "1343253245"};
	for_each(it2.begin(), it2.end(), print(5));


	vector<double> it3 = { 1.1, 2.3, 3.4, 4.7, 6.9, 7.1 };
	for_each(it3.begin(), it3.end(), print(5.0));
	return 0;
}

总结

仍在持续更新中~
如果对您有所帮助,请点个赞!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值