函数对象与谓词

函数对象

重载函数调用操作符的类,其对象常称为函数对象(function object),即他们的行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过”对象名+(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待.
这是通过重载类的operator()来实现的.
“在标准类库中,函数对象被广泛地使用以获得弹性”,在标准库中的很多算法都可以使用函数对象或者函数来作为自定的回调行为.

《函数对象与谓词》

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>

using namespace std;


// 函数对象 重载了()
template <typename T>
class ShowElem
{ 
public:
	ShowElem()
	{ 
		n = 0;
	}
	void operator()(T &t)
	{ 
		n++;
		// printN();
		cout << t << endl;
	}
	void printN()
	{ 
		cout << " n : " << n << endl;
	}
private:
	int n;

};
// 模板函数
template <typename T>
void FuncShowElem(T &t)
{ 
	cout << t << endl;
}
// 普通函数
void FuncShowElem2(int &t)
{ 
	cout << t << endl;
}



// 函数对象和普通函数的区别
void main01()
{ 
	int a = 10;
	ShowElem<int> showElem;

	// =======================================
	showElem(a);   // 函数对象的执行很想一个函数调用 -- 又叫做仿函数

	FuncShowElem<int>(a);
	FuncShowElem2(a);
	// =======================================
}


// 函数对象是属于类对象,能突破函数的概念,能保持调用状态信息
// 函数对象的好处
void main02()
{ 
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	
	for_each(v1.begin(), v1.end(), ShowElem<int>());   // 匿名仿函数对象

	cout << endl;

	
	for_each(v1.begin(), v1.end(), FuncShowElem2);	// 通过回调函数

	ShowElem<int> show1;
	// 函数对象做函数参数

	/* template<class _InIt, class _Fn> inline _Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last) _Adl_verify_range(_First, _Last); auto _UFirst = _Get_unwrapped(_First); const auto _ULast = _Get_unwrapped(_Last); for (; _UFirst != _ULast; ++_UFirst) { _Func(*_UFirst); } return (_Func); } */
	// for_each 算法的函数对象的传递 是元素值传递,不是引用传递
	// 把形参的运算结果拷贝出来了

	/* * 要分清楚stl算法返回的值是迭代器还是谓词(函数对象) 是 stl算法入门的重要点 */
	show1 = for_each(v1.begin(), v1.end(), show1);
	show1.printN();



}



int main()
{ 

	// main01();
	main02();
	system("pause");
	return 1;
}
一元谓词
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>

using namespace std;

template <typename t>
class IsDiv
{ 
public:
	IsDiv(const t &divisor)
	{ 
		this->divisor = divisor;
	}
	bool operator()(t &t)
	{ 
		return (t%divisor == 0);
	}
private:
	t divisor;
};




void main03()
{ 
	vector<int> v2;
	for (int i = 10; i < 33; i++)
	{ 
		v2.push_back(i);
	}

	int a = 4;
	// IsDiv<int> myDiv(a);

	vector<int>::iterator it;
	// find_if() 返回的是一个迭代器
	it = find_if(v2.begin(), v2.end(), IsDiv<int>(a));

	if (it == v2.end())
	{ 
		cout << "容器中没有被4整除的元素" << endl;
	}
	else
	{ 
		cout << "第一个是被4整除的元素是:" << *it << endl;
	}
	// find_if(v2.begin(), v2.end(), myDiv<int>(4));
}



int main2_1()
{ 
	main03();
	system("pause");
	return 0;
}

一元谓词

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>

using namespace std;

template <typename t>
class IsDiv
{ 
public:
	IsDiv(const t &divisor)
	{ 
		this->divisor = divisor;
	}
	bool operator()(t &t)
	{ 
		return (t%divisor == 0);
	}
private:
	t divisor;
};




void main03()
{ 
	vector<int> v2;
	for (int i = 10; i < 33; i++)
	{ 
		v2.push_back(i);
	}

	int a = 4;
	// IsDiv<int> myDiv(a);

	vector<int>::iterator it;
	// find_if() 返回的是一个迭代器
	it = find_if(v2.begin(), v2.end(), IsDiv<int>(a));

	if (it == v2.end())
	{ 
		cout << "容器中没有被4整除的元素" << endl;
	}
	else
	{ 
		cout << "第一个是被4整除的元素是:" << *it << endl;
	}
	// find_if(v2.begin(), v2.end(), myDiv<int>(4));
}



int main2_1()
{ 
	main03();
	system("pause");
	return 0;
}
二元函数对象
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>

using namespace std;

// 二元函数对象
template <typename T>
class SumAdd
{ 
public:
	T operator()(T t1, T t2)
	{ 
		return t1 + t2;
	}
};


void main04()
{ 
	// v1 v2 做运算 加到 v3
	vector<int> v1, 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(10);
	// transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>());
	// transform 把运算结果的 迭代器的开始的位置 返回出来
	transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>());
	
	for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++)
	{ 
		cout << *it << endl;
	}


}



int main4_1()
{ 
	main04();
	system("pause");
	return 0;
}






二元谓词
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>
using namespace std;


void FuncShowEl(int &t)
{ 
	cout << t << " ";
}


bool MyCompare(const int &a, const int &b)
{ 
	return a < b;	// 从小到大
}

// 二元谓词 比较大小
void main05()
{ 
	vector<int> v(10);
	for (int i = 0; i < 10; i++)
	{ 
		int tmp = rand() % 100;
		v[i] = tmp;
	}


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

	cout << endl;
	// 遍历
	for_each(v.begin(), v.end(), FuncShowEl);
	// 排序
	sort(v.begin(), v.end(), MyCompare);
	for_each(v.begin(), v.end(), FuncShowEl);
	cout << endl;
}




int main()
{ 
	main05();

	system("pause");
	return 0;
}

二元谓词在set集合中的应用
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <algorithm>
#include <functional>
#include <string>
using namespace std;


struct CompareNoCase
{ 
	bool operator()(const string &str1, const string &str2) const
	{ 
		string str1_;
		str1_.resize(str1.size());
		// tolower 预定义函数对象
		transform(str1.begin(), str1.end(), str1_.begin(), tolower);

		string str2_;
		str2_.resize(str2.size());
		transform(str2.begin(), str2.end(), str2_.begin(), tolower);


		return (str1_ < str2_); // 从小到大进行排序
	}
};


void main06()
{ 
	set<string> set1;
	set1.insert("bbb");
	set1.insert("aaa");
	set1.insert("ccc");
	// find函数 默认是区分大小写的
	set<string>::iterator it = set1.find("aaa");
	if (it == set1.end())
	{ 
		cout << "没有查找到 aaa" << endl;
	}
	else
	{ 
		cout << "查找到 aaa" << endl;
	}

	set<string, CompareNoCase> set2;
	set2.insert("bbb");
	set2.insert("aaa");
	set2.insert("ccc");

	set<string, CompareNoCase>::iterator it2 = set2.find("aAa");
	if (it2 == set2.end())
	{ 
		cout << " 没有 查找到 aAa " << endl;
	}
	else
	{ 
		cout << " 不区分大小的的查找 查找到 aAa " << endl;
	}


}


int main()
{ 
	main06();
	system("pause");
	return 0;
}
    原文作者:汤愈韬
    原文地址: https://blog.csdn.net/qq_38200548/article/details/101438739
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞