C ++ conjunto y mulitset el funtor (objeto de función)

Antes de aprender funtor (función objetivo), primero tenemos que entender los principios subyacentes se establece con la especie de mulitset!

mulitset se establece con un recipiente, un contenedor de recogida.
El conjunto de elementos de almacenamiento es siempre único y mulitset puede almacenar los mismos elementos.

Este artículo será un ejemplo para ilustrar, el uso conjunto mulitset y exactamente lo mismo!

Si no sabe cómo configurar y contenedores mulitest, puede ordenar el siguiente enlace para aprender:
https://blog.csdn.net/cpp_learner/article/details/104751672


set y mulitset se almacenan secuencialmente elementos.

Antes de ver el ejemplo, la primera mirada, set y mulitset tiene dos funciones para elevar el mismo tipo: menos y mayor

Donde menos es el orden de la clasificación, pero mayor es el orden inverso!

Véase el siguiente ejemplo 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;
}

tiro de ejecución:
Aquí Insertar imagen Descripción

Código, Inversión del orden de 1 - 10 tiendas en s1, s3 0--9 la secuencia positiva almacenada en la entrada, pero el resultado es con respecto al número, n es la salida s1 orden, y S3 es la salida a la inversa!

Tal resultado es menor y mayor de estas dos funciones del fantasma.

Estas dos funciones se encuentran en el archivo de cabecera #include <functional>en.

Nos fijamos en el código específico subyacente en estas dos funciones:
Aquí Insertar imagen Descripción

Podemos saber que en realidad es la realización del principio plantillas de funciones subyacentes y sobrecargada operador ().
Por ejemplo:
menos en comparación si 3 y 4, se volverá a verdadero, el frente de 4 filas 3 formarán un orden de clasificación.
mayor, el relativamente 3 y 4, se volverá a falso, habrá 3 en la parte posterior 4 está formado en el orden inverso.


Bueno, sé que esto, si volvemos: el recipiente siempre será imposible almacenar elementos de tipo int, también almacenar otros tipos de elementos, tales como clases de objetos!
Por eso, cuando se almacena un objeto, cómo se compara a solucionar el problema?

Nos fijamos en el código:

#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;
}

Y todavía casi el mismo código, pero más para definir una clase Estudiante.
Ponemos un objeto en un recipiente, y luego imprimirlo y vemos cómo se ordenó!

Después de ejecutar:
Aquí Insertar imagen Descripción
ejecutar realmente el error, el compilador no lo hace por ah, ¿cómo se va ah? ? ?

Vemos la primera fila de la línea roja pintada, lo que indica que las razones equivocadas!

Es el "<" operador emite.

Echemos un vistazo en el código subyacente :( sólo un ejemplo para menos)
Aquí Insertar imagen Descripción

Él es una plantilla bueno, cuando la plantilla se reemplaza con las clases, los objetos no son directamente comparables, por lo que no pasará el compilador.
La solución es: Cuando se quiere utilizar menos, sobrecargado <operador. Cuando se desea utilizar mayor, recarga> operador!
Estoy aquí tanto para escribir!

#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;
}

tiro de ejecución:
Aquí Insertar imagen Descripción

ejecución perfecta! ! !


Pues bien, con más de allanando el camino, podemos imitar en términos de función (objeto de función) una

Functor (objeto de función)

concepto Functor

  1. Aunque los punteros de función son ampliamente utilizados para implementar funciones de devolución de llamada, pero C ++ también proporciona una forma importante para implementar la función de devolución de llamada, que es el objeto de función.
  2. funtor, traducido en la función objetivo, la pseudo-función, que es un objeto de clase común para sobrecargado ") (" operador. Gramaticalmente hablando, es similar a un comportamiento función ordinaria.
  3. El archivo de cabecera contiene una mayor funcionalidad <> y menos <> es un objeto de función.

El principio facilidad mayor y menos citados a continuación.

struct mayor
{
operador booleano () (const int y iLeft, const int & iRight)
{
return (iLeft> iRight);
}
}

struct menos
{
operador bool () (int const y iLeft, const int & iRight)
{
return (iLeft <iRight);
}
}

operador de conjunto / setmulti llama al objeto de función es un método recipiente () para comparar el tamaño de los dos valores.


Uso funtor podemos llamar a su propio objeto de función para escribir su propio conjunto de clases y mulitset.

Por ejemplo:
con menos, por ejemplo:

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

Copiar el código anterior a él:

#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;
}

Después se define funtor, que puede ser utilizado para reemplazar menor / mayor es el.
Por ejemplo: set <Estudiante, FunStudent> s1 ;

tiro de ejecución:
Aquí Insertar imagen Descripción

También una perfecta corre! ! !


Tal vez alguien le preguntará, funtor propia definición de y por encima de la salida no cambia ah, todavía lo hago tanto código está haciendo? ?

Normal, de hecho, una gran parte de su utilidad cuando hay una tal pregunta!

Por ejemplo, que es una clase, somos libres para volver a escribir para que mejor puede funcionar!
Como un ejemplo:

// 仿函数(函数对象)
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;
};

Para que pueda obtener de él para volver valor!
También, puede escribir código a sí mismos una gran cantidad de otros usos dependiendo de la mirada! !


En este caso, las funciones de copia y también están terminados, en general, la función de la imitación es también muy práctico!

Publicado 42 artículos originales · ganado elogios 27 · vistas 8484

Supongo que te gusta

Origin blog.csdn.net/cpp_learner/article/details/104730577
Recomendado
Clasificación