C++11-5 - envoltorios de funciones

c++

Prefacio:

Vue框架:
OJ算法系列:Aprende trucos de magia Vue del proyecto - explicación detallada del algoritmo
Linux操作系统:Fenghou Qimen - linux

contenedor de funciones:

objeto de llamada:

  • Clasificación de objetos de llamada:
int ret = func(x);
//func可能是什么呢?
  1. Nombre de la función
  2. puntero de función
  3. objeto funtor
  4. objeto de expresión lambda

Eficiencia de la plantilla:

  • Demasiados objetos de llamada, lo que lleva a un uso ineficiente de las plantillas:
template<class F, class T>
T useF(F f, T t){
    
    
	static int count = 0;	//一定为static
	cout<<"count : "<<count++<<endl;
	cout<<"&count : "<<&count<<endl;
	return f(x);
}

//f的三种类型:
double func1(double x){
    
    
	return i/2;
}
struct Functor{
    
    
	double operator()(double x){
    
    
		return x/3;
	}
};
auto func2 = [](double x){
    
    
	return x/4;
};

int main(){
    
    
	useF(func1, 10);
	useF(Functor(), 10);
	useF(func2, 10);
	return 0;
}
  • Resultado actual: tres direcciones de conteo diferentes
  • Análisis de causa:
    1. la clase F corresponde a tres tipos de hormigón diferentes
    2. Crea una instancia de tres funciones useF()
    3. Cada función useF() contiene su propia variable estática

Envoltura:

efecto:

  • Envolver diferentes objetos invocables en el mismo tipo
    también se considera como la misma categoría cuando el reconocimiento de plantilla
  • Es equivalente a un aumento en el tipo del objeto que llama,
    especialmente el auto que no era fácil de usar, y
    ahora el tipo también se puede registrar como función<()> de acuerdo con los parámetros y el valor de retorno;

uso:

  • Archivo principal:
#include <functional>
  • declaración:
//对函数/函数指针:
function<double(double)> f1 = func1;

//对仿函数类:
function<double(double)> f2 = Functor();

//对lambda表达式:
function<double(double)> f3 = func2;

Función interna de la clase Wrapper:

Función estática en la clase contenedora:

  • Casi lo mismo que envolver una función no intrínseca
class Calculator{
    
    
	public:
		int sum(int x, int y){
    
    
			return x+y;
		}
};
int main(){
    
    
	function<int(int, int)> f4 = &Calculator::sum;	//可不加&
	return 0;
}

Función no estática en la clase contenedora:

  • Hay dos diferencias con respecto a envolver funciones ordinarias:
    1. más ampersand
    2. Declarar la clase a la que pertenece la función estática en la clase contenedora
    3. Se debe pasar un objeto de instancia al llamar
class Calculator{
    
    
	public:
		static int sub(int x, int y){
    
    
			return x+y;
		}
};
int main(){
    
    
	function<int(Calculator, int, int)> f4 = &Calculator::sub;
	f4(Calculator(), 1, 2);
	return 0;
}

probar:

  • Demostrar que después del envoltorio, todas las funciones pertenecen a la misma clase:
#include <iostream>
#include <cstring>
#include <functional>
using namespace std;
template<class F, class T>
T useF(F f, T t){
    
    
	static int count = 0;	//一定为static
	cout<<"count : "<<count++<<endl;
	cout<<"&count : "<<&count<<endl;
	return f(t);
}

double func1(double x){
    
    
	return x/2;
}
struct Functor{
    
    
	double operator()(double x){
    
    
		return x/3;
	}
};
auto func2 = [](double x){
    
    
	return x/4;
};
class Test{
    
    
	public:
		static double sfunc(double x){
    
    
			return x/5;
		}
		double dfunc(double x){
    
    
			return x/6;
		}
};
int main(){
    
    
	function<double(double)> f1 = func1;
	function<double(double)> f2 = Functor();
	function<double(double)> f3 = func2;
	useF(f1, 10);
	useF(f2, 10);
	useF(f3, 10);
	function<double(double)> f4 = Test::sfunc;
	function<double(Test, double)> f5 = &Test::dfunc;
	useF(f4, 10);
	cout<<"f5:"<<f5(Test(), 10);
	/*
		useF(f5, 10);
		f5和f1~f4传参不同,所以  暂时  不能放入useF()函数中
		学完绑定后即可
	*/
	return 0;
}
  • resultado de la operación:
    función<>

enlazar enlazar:

efecto:

Ajuste el orden de paso de parámetros:

  • placeholders::_n: Indica que el valor de la posición actual se pasa al parámetro n de la función
void func(int x, int y){
    
    
	cout<<"x:"<<x <<"  "<<"y:"<<y<<endl;
}
function<int(int ,int)> f1 = bind(func, placeholders::_1, placeholders::_2);
f1(1, 2);

function<int(int ,int)> f2 = bind(func, placeholders::_2, placeholders::_1);
f2(1, 2);
  • Resultado actual:
    1 2
    2 1

Ajuste el número de parámetros:

  • Para funciones no estáticas en la clase, vincule la clase + proporcione el objeto:
class Test{
    
    
	public:
		static double sfunc(double x){
    
    
			return x/5;
		}
		double dfunc(double x){
    
    
			return x/6;
		}
};

function<double(Test, double)> f5 = &Test::dfunc;
f5(Test(), 10);
function<double(Test, double)> f6 = bind(&Test::dfunc, Test());
f6(10);
  • Vincule la función no estática + el objeto de clase en la clase a la función () en un solo paso

Supongo que te gusta

Origin blog.csdn.net/buptsd/article/details/126893596
Recomendado
Clasificación