C++11-5 - 関数ラッパー

C++

序文:

Vue框架:プロジェクトからVue の
OJ算法系列:魔法のトリックを学ぶ - アルゴリズムの詳細な説明
Linux操作系统:Fenghou Qimen - linux

関数ラッパー:

呼び出しオブジェクト:

  • 呼び出しオブジェクトの分類:
int ret = func(x);
//func可能是什么呢?
  1. 関数名
  2. 関数ポインタ
  3. ファンクターオブジェクト
  4. ラムダ式オブジェクト

テンプレートの効率:

  • 呼び出しオブジェクトが多すぎるため、テンプレートの使用が非効率的になります。
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;
}
  • 実行結果: 3 つの異なるカウント アドレス
  • 原因分析:
    1. クラス F は 3 つの異なる具象タイプに対応します
    2. 3 つの useF() 関数をインスタンス化する
    3. 各 useF() 関数には独自の静的変数が含まれます

ラッパー:

効果:

  • 異なる呼び出し可能オブジェクトを同じ型にラップすることも、
    テンプレート認識時に同じカテゴリとみなされます。
  • これは呼び出し元オブジェクトの型、
    特に使いにくかった auto の型が増加したことに相当し、
    パラメーターと戻り値に応じて型を function<()> として記録することもできるようになりました。

使用法:

  • ヘッド ファイル:
#include <functional>
  • 声明:
//对函数/函数指针:
function<double(double)> f1 = func1;

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

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

ラッパークラスの内部関数:

ラッパークラスの静的関数:

  • 非組み込み関数のラップとほぼ同じ
class Calculator{
    
    
	public:
		int sum(int x, int y){
    
    
			return x+y;
		}
};
int main(){
    
    
	function<int(int, int)> f4 = &Calculator::sum;	//可不加&
	return 0;
}

ラッパークラスの非静的関数:

  • 通常の関数のラップとは 2 つの違いがあります。
    1. プラスアンパサンド
    2. 静的関数が属するクラスをラッパークラスで宣言します。
    3. 呼び出し時にインスタンス オブジェクトを渡す必要があります。
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;
}

証明:

  • ラッパーの後のすべての関数が同じクラスに属することを証明します。
#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;
}
  • 操作結果:
    関数<>

バインドバインディング:

効果:

パラメータを渡す順序を調整します。

  • placeholders::_n: 現在位置の値が関数の 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);
  • 実行結果:
    1 2
    2 1

パラメータの数を調整します。

  • クラス内の非静的関数の場合は、クラスをバインドしてオブジェクトを提供します。
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);
  • クラス内の非静的関数 + クラス オブジェクトを 1 ステップで function() にバインドします。

おすすめ

転載: blog.csdn.net/buptsd/article/details/126893596