C++ 有关于函数对象以及谓词部分练习以及知识点的总结

#include<iostream>

using namespace std;

#include"algorithm"  //算法的头文件
#include"functional"  //同为算法的头文件
#include"set"
#include"vector"
#include"list"
#include"string"


//注意:!!!!一定要分得清楚算法的返回值是迭代器,还是谓词(函数对象)!!!!
//例如for_each()算法返回了一个函数对象


/*函数对象与普通函数以及模板函数的区别*/


//函数对象  重载了函数调用操作符 : ()
//类模板  实现
template<typename T>  //这里是只有一个函数参数 是一元函数对象

class myClass
{
public:
	myClass()  //构造函数
	{
	//	n = 0;
	}

	void printhM()
	{
	//	cout <<"n ="<< n << endl;
	}
	void operator()(T a)
	{
		//n++;
		//printhM();
		cout << a << " " ;
	}

public:
	T n;
};


//普通函数

void printfM2(int a)
{
	cout << "普通函数" << a << endl;
}


//函数模板
template<typename T>

void printfM1(T a)
{
	cout << "函数模板"<<a << endl;
}



//函数对象与普通函数以及模板函数的区别
void main01()
{
	int a;
	a = 20;
	myClass<int>  showmyClass;
	showmyClass.printhM();//调用成员函数
	showmyClass(a);   //函数对象  该类模板重载了()操作符,因此这里看起来非常类似于一个函数的调用

	printfM1<int>(a);  //函数模板的调用  采用显示调用法
	printfM2(a);      //普通函数的调用
}


//函数对象属于类对象,可以突破函数的概念, 保持调用状态信息
//函数对象的好处:
//for_each算法当中的参数
//for_each算法当中的返回值
void main02()
{
	vector<int> m_vec;

	m_vec.push_back(1);
	m_vec.push_back(6);
	m_vec.push_back(9);

	for_each(m_vec.begin(), m_vec.end(), myClass<int>( ));  //匿名函数对象  匿名仿函数
	for_each(m_vec.begin(), m_vec.end(), printfM2);  // 回调函数 实现了任务的编写者与任务的调用者的分离



	//因为for_each算法当中,第三个参数是传入一个值,而不是引用,因此使用printhM()在for_each外打印时依旧为0 
	myClass<int> c_myclass;
	for_each(m_vec.begin(), m_vec.end(), c_myclass);  //不采用匿名函数
	c_myclass.printhM();

	//解决办法

	//首先按F12观察原函数  发现返回一个函数_Func  因此用一个函数对象来接返回值便可以
	/*template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Func);
	_For_each(_Unchecked(_First), _Unchecked(_Last), _Func);

	return (_STD move(_Func));
	}*/

	myClass<int> c_myclass_1;
	c_myclass_1 = for_each(m_vec.begin(), m_vec.end(), c_myclass_1);  //不采用匿名函数
	c_myclass_1.printhM();


}


//一元谓词
template <typename T>
class Exp
{
public:

	bool operator()(T a)   //含有一个参数 并且返回一个bool类型的值
	{
		return (a % 4 == 0);
	}
private:
	int a;

};



//一元谓词 通过一元谓词判断一个数能否被4整除
void main03()
{
	Exp<int> c_e;
	vector<int> v1;

	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(16);
	v1.push_back(4); 
	vector<int>::iterator it;

	it=find_if(v1.begin(), v1.end(), Exp<int>());  //find_if  返回一个迭代器

	if (it == v1.end())
	{
		cout << "没有数可以被4整除" << endl;
	}

	else
	{
		cout << "第一个能被4整除的数"<<*it << endl;
	}

}


//二元函数对象  类中默认的访问为private  struct中是public
template<typename T>

class ADD
{
public:
	T operator()(T a, T b)
	{
		return a + b;
	}
};

void  main04()
{
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;

	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	v2.push_back(2);
	v2.push_back(4);
	v2.push_back(6);

	v3.resize(3);   //重新设置vector的大小

	transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), ADD<int>());   //匿名函数的二元函数对象
	//transform 将运算结果的迭代器位置返回


	for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++)
	{
		cout << *it << endl;
	}


}

//二元谓词   从大到小排列
bool funComplare(int a,int b)
{
	return a > b;
}

void main05() //二元谓词  案例:实现对于一个vector的排序
{
	vector<int> v1;

	for (int i = 0; i < 10; i++)
	{
		int tmp = rand() % 100;  //0-100的未知数
		v1.push_back(tmp);
	}

	//采用 for_each 算法实现遍历
	for_each(v1.begin(), v1.end(), myClass<int>());

	//利用二元谓词实现排序
	sort(v1.begin(),v1.end(), funComplare);

	cout << endl;

	//采用 for_each 算法实现遍历
	for_each(v1.begin(), v1.end(), myClass<int>());


}

//实现二元谓词
struct withNocase
{
	bool operator()(const string &strLeft, const string &strRight)
	{
		string strLeft_;
		strLeft_.resize(strLeft.size());
		transform(strLeft.begin(), strLeft.end(), strLeft_.begin(),tolower);

		string strRight_;
		strRight_.resize(strRight.size());
		transform(strRight.begin(), strRight.end(), strRight_.begin(), tolower);

		return (strRight_ < strLeft_);

	}
};

void main06()  //实现在set中的find函数的不区分大小写的查找
{
	set<string> myset;

	myset.insert("hkashdkj");
	myset.insert("torres");
	myset.insert("bob");
	myset.insert("Abc");

	//利用for_each 算法实现遍历
	for_each(myset.begin(), myset.end(), myClass<string>());

	set<string>::iterator it = myset.find("abc"); 

	if (it != myset.end())
	{
		cout << "查找到该元素" << endl;
	}
	else
	{
		cout << "没有查到该元素" << endl;
	}


	cout << "----------------------" << endl;
	set<string,withNocase> myset_;

	myset_.insert("hkashdkj");
	myset_.insert("torres");
	myset_.insert("bob");
	myset_.insert("Abc");

	//利用for_each 算法实现遍历
	for_each(myset_.begin(), myset_.end(), myClass<string>());

	set<string, withNocase>::iterator it_ = myset_.find("abc");

	if (it_ != myset_.end())
	{
		cout << "查找到该元素" << endl;
	}
	else
	{
		cout << "没有查到该元素" << endl;
	}

	


}


void main()
{
	//main01();//普通函数与函数模板的区别
	//main02();  //函数对象属于类对象,可以突破函数的概念, 保持调用状态信息
    //main03();  //一元谓词
	//main04();  //二元函数对象
	//main05();  //二元谓词
	main06();  //二元谓词在set集合中的应用
	system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值