13 STL-函数对象

 重新系统学习c++语言,并将学习过程中的知识在这里抄录、总结、沉淀。同时希望对刷到的朋友有所帮助,一起加油哦!

 

每一次学习都是为了追求智慧!

写在前面,本篇章主要介绍STL中常用容器函数对象。

1.1 函数对象

1.1.1 函数对象概念

概念:

        重载函数调用操作符的类,称为函数对象

        函数对象使用重载的()时,行为类似函数调用,也叫仿函数

本质:

        函数对象(仿函数)是一个类,不是一个函数。

 

1.1.2 函数对象使用

特点:

        1 函数对象在使用时,可以像普通函数一样调用,可以有参数,有返回值;

        2 函数对象超出普通函数概念,可以有自己的状态,定义一些内部成员属性;

        3 函数对象可以作为参数传递。

示例:

#include <iostream>
#include <string>

using namespace std;

//1 函数对象在使用时,可以像普通函数一样调用,可以有参数,有返回值;
class MyAdd {
public:
	int operator()(int a, int b) {
		return a + b;
	}
};

void test() {
	MyAdd myAdd;
	cout << myAdd(1, 3) << endl;
}

//2 函数对象超出普通函数概念,可以有自己的状态,定义一些内部成员属性;
class MyPrint {
public:
	void operator()(string s) {
		cout << s << endl;
		count++;
	}

	int count=0;
};

void test2() {
	MyPrint p;
	p("hello");
	p("hello");
	p("hello");
	p("hello");

	// 使用到仿函数成员属性,可以统计调到函数的次数。
	cout << "call MyPrint times:" << p.count << endl;
}

//3 函数对象可以作为参数传递。
void doPrint(MyPrint& p,string s) {
	p(s);
	p(s);
	p(s);
}
void test3(){
	MyPrint p;
	doPrint(p,"hi");
}

int main() {
	//test();
	//test2();
	test3();

	system("pause");
	return 0;
}

 

1.2 谓词

1.2.1 概念

概念:

        谓词:防函数,返回bool类型。

        一元谓词:一个参数的谓词

        二元谓词:两个参数的谓词

 

1.2.2 一元谓词

使用vector<int>::iterator pos = find_if(v.begin(), v.end(), GreaterFive());来体会一元谓词的使用。

 

示例:

#include <iostream>
#include <string>
#include<vector>
using namespace std;

// 一元谓词
class GreaterFive {
public:
	bool operator()(int val)const {
		return val > 5;
	}
};

void test() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	// 查找大于5的数字
	// GreaterFive() 是匿名函数对象
	vector<int>::iterator pos = find_if(v.begin(), v.end(), GreaterFive());
	if (pos == v.end()) {
		cout << "未找到大于5的数字" << endl;
	}
	else {
		cout << "未找到大于5的数字:" << *pos << endl;
	}
}

int main() {
	test();

	system("pause");
	return 0;
}

 

1.2.3 二元谓词

    // 利用仿函数MyCompare()改变排序规则 大到小
    sort(v.begin(), v.end(), MyCompare());

示例:

#include <iostream>
#include <string>
#include<vector>
#include<algorithm>
using namespace std;

// 二元谓词
class MyCompare {
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};
void myPrint(const vector<int>& v) {
	for (auto item : v) {
		cout << item << " ";
	}
	cout << endl;
}

void test() {
	vector<int> v;
	v.push_back(1);
	v.push_back(3);
	v.push_back(4);
	v.push_back(2);
	v.push_back(2);

	sort(v.begin(), v.end());
	myPrint(v);

	// 利用仿函数改变排序规则 大到小
	sort(v.begin(), v.end(), MyCompare());
	myPrint(v);

}

int main() {
	test();

	system("pause");
	return 0;
}

 

1.3 内建函数对象

1.3.1 内建函数意义

概念:
        STL内部提供了一些通用函数对象

分类:

        算术仿函数

        关系仿函数

        逻辑仿函数

用法:

        和普通函数完全相同

        需要引入头文件 #include<functional>

 

1.3.2 算术仿函数

能力:

        实现四则运算

        negate 是一元运算,其他都是二元运算。

仿函数原型:

  • template<class T> T plus<T>                         //加法仿函数
  • template<class T> T minus<T>                      //减法仿函数
  • template<class T> T multiplies<T>                 //乘法仿函数
  • template<class T> T divides<T>                    //除法仿函数
  • template<class T> T modulus<T>                 //取模仿函数
  • template<class T> T negate<T>                   //取反仿函数

示例:

#include <iostream>
#include <string>
#include<functional>//内建函数对象头文件
using namespace std;

//template<class T> T plus<T> //加法仿函数
//template<class T> T minus<T> //减法仿函数
//template<class T> T multiplies<T> //乘法仿函数
//template<class T> T divides<T> //除法仿函数
//template<class T> T modulus<T> //取模仿函数
//template<class T> T negate<T> //取反仿函数

// 一元运算 
void test() {
	//negate 取反仿函数
	negate<int> n;
	cout << n(10) << endl;// -10
}

// 二元运算 
void test2() {
	// plus 加法
	plus<int> plus;
	cout<<" 1 + 5 =" << plus(1, 5) << endl;

	//minus 减法
	minus<int> minus;
	cout << " 10 - 2 = " << minus(10, 2) << endl;
}

int main() {
	//test();
	test2();

	system("pause");
	return 0;
}

 

1.3.3 关系仿函数

能力:

        实现关系对比。

 

algotithm 算法库里,sort函数是默认的升序,使用的就是less<T> 。

 

仿函数原型:

  • template<class T> bool equal_to<T>                   //等于
  • template<class T> bool not_equal_to<T>            //不等于
  • template<class T> bool greater<T>                      //大于
  • template<class T> bool greater_equal<T>           //大于等于
  • template<class T> bool less<T>                           //小于
  • template<class T> bool less_equal<T>                 //小于等于

示例:

#include <iostream>
#include <string>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;

class MyCompare {
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};

void printVector(const vector<int>& v) {
	for (auto item : v) {
		cout << item << " ";
	}
	cout << endl;
}

void test() {
	vector<int> v;
	v.push_back(10);
	v.push_back(30);
	v.push_back(50);
	v.push_back(20);
	v.push_back(40);

	vector<int> v2(v);

	printVector(v);

	// 使用sort默认升序
	sort(v.begin(), v.end());
	printVector(v);

	// 自己写仿函数 降序
	sort(v.begin(), v.end(), MyCompare());
	printVector(v);

	//利用functional 中 内建关系仿函数:greater<int>() 降序
	// greater<int>()就实现了自己定义的MyCompare()
	cout << "------------v2" << endl;
	printVector(v2);
	sort(v2.begin(), v2.end(), greater<int>());
}

int main() {
	test();

	system("pause");
	return 0;
}

输出:

10 30 50 20 40
10 20 30 40 50
50 40 30 20 10
------------v2
10 30 50 20 40
 

1.3.4 逻辑仿函数

能力:

       实现逻辑运算。

仿函数原型:

  • template<class T> bool logical_and<T>                 //逻辑与
  • template<class T> bool logical_or<T>                 //逻辑或
  • template<class T> bool logical_not<T>                 //逻辑非

示例:

#include <iostream>
#include <string>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;

void printVector(const vector<bool>& v) {
	for (auto item : v) {
		cout << item << " ";
	}
	cout << endl;
}


void test() {
	vector<bool>v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	printVector(v);

	// 利用逻辑非仿函数,将v的数据搬运到v2,并对数据取反
	vector<bool>v2;
	v2.resize(v.size());
	// transform 搬运函数
	// logical_not<bool>() 逻辑非仿函数
	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
	printVector(v2);
}

int main() {
	test();

	system("pause");
	return 0;
}

 

 

 


posted on 2022-11-28 18:48  爱学习的小灵子  阅读(24)  评论(0编辑  收藏  举报