C++11 - envoltorios de función
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可能是什么呢?
- Nombre de la función
- puntero de función
- objeto funtor
- 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:
- la clase F corresponde a tres tipos de hormigón diferentes
- Crea una instancia de tres funciones useF()
- 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:
- más ampersand
- Declarar la clase a la que pertenece la función estática en la clase contenedora
- 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:
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