C ++ set & mulitset the functor (function object)

Before learning functor (function object), we must first understand the underlying principles set with mulitset sort of!

mulitset is set with a container, a collection container.
The set of storage elements is always unique, and mulitset can store the same elements.

This article will set an example to illustrate, mulitset usage and set exactly the same!

If you do not know how to set and mulitest container, you can order the following link to learn:
https://blog.csdn.net/cpp_learner/article/details/104751672


mulitset set and are sequentially stored elements.

Before watching the example, first look, set and mulitset has two functions to raise the same sort: less and greater

Where less is the order of the sort, but greater is the reverse order!

See the following example a:

#include <iostream>
#include <Windows.h>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

int main(void) {
	set<int> s1;	// 等同于默认值:set<int, less<int>> s1;
	//set<int, less<int>> s1;	// 正序排序

	for (int i = 0; i < 10; i++) {
		s1.insert(10 - i);
	}

	cout << "less:" << endl;
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;




	set<int, greater<int>> s3;	// 倒序排序

	for (int i = 0; i < 10; i++) {
		s3.insert(i);
	}

	cout << "greater:" << endl;
	for (set<int>::iterator it = s3.begin(); it != s3.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;

	system("pause");
	return 0;
}

Run shot:
Here Insert Picture Description

Code, we reverse order of 1 - 10 stores into s1, the 0--9 s3 positive sequence stored in the intake, but the result is out of the number, n is the order output s1, and s3 is the reverse output!

Such a result are less and greater of these two functions out of the ghost.

These two functions are in the header file #include <functional>in.

We look at the underlying specific code in these two functions:
Here Insert Picture Description

We can know that it is actually the realization of the principle underlying function templates and overloaded () operator.
For example:
less in comparison if 3 and 4, it will return to true, the front 4 rows 3 will form a sort order.
greater, the relatively 3 and 4, it will return to false, 3 will be at the back 4 is formed in reverse order.


Well, I know this, if we come back: the container will always be impossible to store elements of type int, also store other types of elements, such as object classes!
So when an object is stored, how he compares to sort it?

We look at the code:

#include <iostream>
#include <Windows.h>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

class Student {
public:
	Student(int age, const char* name) {
		this->age = age;

		this->name = new char[strlen(name) + 1];
		strcpy_s(this->name, strlen(name) + 1, name);
	}

	~Student() {
		if (name) {
			delete[] name;
			name = NULL;
			age = 0;
		}
	}

	// 拷贝构造函数
	Student(const Student& student) {
		this->age = student.age;

		this->name = new char[strlen(student.name) + 1];
		strcpy_s(this->name, strlen(student.name) + 1, student.name);
	}

	int getAge() const {
		return age;
	}

	char* getName() const {
		return name;
	}

private:
	int age;
	char* name;
};


int main(void) {
	set<Student> s1;	// 等同于默认值:set<Student, less<Student>> s1;

	// 将两个临时对象插入容器中
	s1.insert(Student(20, "张三"));
	s1.insert(Student(22, "李四"));

	for (set<Student>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << "年龄:" << it->getAge() << " 姓名:" << it->getName() << endl;
	}

	system("pause");
	return 0;
}

And still just about the same code, but more to define a Student class.
We put an object into a container, and then print it out and see how he ordered!

After running:
Here Insert Picture Description
actually run error, the compiler does not by ah, how is this going ah? ? ?

We see the first row of painted red line, indicating that the wrong reasons!

Is the "<" operator issues.

Let's look at the underlying code :( just an example to less)
Here Insert Picture Description

He is a template hey, when the template is replaced with classes, objects are not directly comparable, so the compiler will not pass.
The solution is: When you want to use less, overloaded <operator. When you want to use greater, reload> operator!
I am here both to write down!

#include <iostream>
#include <Windows.h>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

class Student {
public:
	Student(int age, const char* name) {
		this->age = age;

		this->name = new char[strlen(name) + 1];
		strcpy_s(this->name, strlen(name) + 1, name);
	}

	~Student() {
		if (name) {
			delete[] name;
			name = NULL;
			age = 0;
		}
	}

	// 拷贝构造函数
	Student(const Student& student) {
		this->age = student.age;

		this->name = new char[strlen(student.name) + 1];
		strcpy_s(this->name, strlen(student.name) + 1, student.name);
	}

	int getAge() const {
		return age;
	}

	char* getName() const {
		return name;
	}

	// < 运算符重载
	bool operator<(const Student student) const {
		return this->age < student.age;
	}

	// > 运算符重载
	bool operator>(const Student student) const {
		return this->age > student.age;
	}

private:
	int age;
	char* name;
};


int main(void) {
	set<Student> s1;	// 等同于默认值:set<Student, less<Student>> s1;

	// 将两个临时对象插入容器中
	s1.insert(Student(20, "张三"));
	s1.insert(Student(22, "李四"));

	for (set<Student>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << "年龄:" << it->getAge() << " 姓名:" << it->getName() << endl;
	}

	system("pause");
	return 0;
}

Run shot:
Here Insert Picture Description

Perfect run! ! !


Well, with more than paving the way, we can imitate in terms of function (function object) a

Functor (function object)

Functor concept

  1. Although the function pointers are widely used to implement callback functions, but C ++ also provides an important way to implement the callback function, that is the function object.
  2. functor, translated into the object function, the pseudo-function, which is a common class object for overloaded "()" operator. Grammatically speaking, it is similar to an ordinary function behavior.
  3. The header file contains a functional greater <> and less <> is a function object.

The principle greater ease and less cited below.

struct greater
{
bool operator() (const int& iLeft, const int& iRight)
{
return (iLeft>iRight);
}
}

struct less
{
bool operator() (const int& iLeft, const int& iRight)
{
return (iLeft<iRight);
}
}

set / setmulti operator calls the function object is a container () method to compare the size of the two values.


Use functor we can call its own function object to write their own set of sorts and mulitset.

For example:
with less, for example:

// 仿函数(函数对象)
class FunStudent {
public:
	bool operator()(const Student& s1, const Student& s2) const {
		return s1.getAge() < s2.getAge();
	}
};

Copy the code above to him:

#include <iostream>
#include <Windows.h>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

class Student {
public:
	Student(int age, const char* name) {
		this->age = age;

		this->name = new char[strlen(name) + 1];
		strcpy_s(this->name, strlen(name) + 1, name);
	}

	~Student() {
		if (name) {
			delete[] name;
			name = NULL;
			age = 0;
		}
	}

	// 拷贝构造函数
	Student(const Student& student) {
		this->age = student.age;

		this->name = new char[strlen(student.name) + 1];
		strcpy_s(this->name, strlen(student.name) + 1, student.name);
	}

	int getAge() const {
		return age;
	}

	char* getName() const {
		return name;
	}

	// < 运算符重载
	bool operator<(const Student student) const {
		return this->age < student.age;
	}

	// > 运算符重载
	bool operator>(const Student student) const {
		return this->age > student.age;
	}

private:
	int age;
	char* name;
};


// 仿函数(函数对象)
class FunStudent {
public:
	bool operator()(const Student& s1, const Student& s2) const {
		return s1.getAge() < s2.getAge();
	}
};


int main(void) {
	set<Student, FunStudent> s1;	// 等同于默认值:set<Student, less<Student>> s1;


	Student stu1(20, "张三");
	Student stu2(22, "李四");

	// 函数对象(仿函数)可以像函数一样直接调用
	//FunStudent funStudent;
	//funStudent(stu1, stu2);


	s1.insert(stu1);
	s1.insert(stu2);

	for (set<Student, FunStudent>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << "年龄:" << it->getAge() << " 姓名:" << it->getName() << endl;
	}


	system("pause");
	return 0;
}

After functor is defined, it can be used to replace less / greater the.
For example: set <Student, FunStudent> s1 ;

Run shot:
Here Insert Picture Description

Also a perfect run! ! !


Maybe someone will ask, functor own definition of and above the output does not change ah, I still do so much code is doing? ?

Normal, in fact, a great deal of his usefulness when there is such a question!

For example, he is a class, we are free to rewrite it so that he can better run!
for instance:

// 仿函数(函数对象)
class FunStudent {
public:
	bool operator()(const Student& s1, const Student& s2) const {
		ret = s1.getAge() < s2.getAge();
		return ret;
	}

	bool getRet() const {
		return ret;
	}
private:
	bool ret;
};

So you can get him to return value!
Also, you can write code themselves a lot of other uses depending on the look! !


Here, and copy functions are also finished, in general, imitation function is also quite practical!

Published 42 original articles · won praise 27 · views 8484

Guess you like

Origin blog.csdn.net/cpp_learner/article/details/104730577