関数テンプレート(C ++ 01)

1.はじめに

C ++では、データの型をパラメーターに渡すこともでき、関数の定義時に特定のデータ型を指定できない場合があります。関数呼び出しが発生すると、コンパイラーは渡された実際のパラメーターに基づいてデータ型を自動的に推測できます。 。これは型のパラメータ化です。

関数テンプレートは、異なる型を使用して呼び出すことができる特別な関数です。同じ関数を持つ関数の場合、コードを繰り返し記述する必要はなく、関数テンプレートは通常の関数と非常によく似ています。違いは、型ができることです。パラメータ化されます。

2.文法

テンプレート関数の構文:

template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型  函数名(形参列表){
  //在函数体中可以使用类型参数
}

カンマで区切って、複数のタイプパラメータを含めることができます,タイプパラメータリストが< >囲まれ、仮パラメータリストが( )囲まれています。

typenameキーワードはキーワードにclass置き換えることもでき、それらの間に違いはありません。C ++の初期のテンプレートのサポートは厳密ではありませんでした。新しいキーワードは導入されませんでした。代わりに、クラスを使用して型パラメーターを指定しました。ただし、クラスキーワードはクラス定義ですでに使用されていました。これはあまりわかりにくいため、後でC ++新しいキーワードtypenameタイプパラメータを定義するために導入されました。ただし、C ++標準ライブラリ、一部のオープンソースプログラムなど、classキーワードを使用するコードはまだたくさんあります。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

#if 0 
//int类型数据交换
void MySwap(int& a, int& b){
    
    
	int temp = a;
	a = b;
	b = temp;
}
//double类型
void MySwap(double& a, double& b){
    
    
	double temp = a;
	a = b;
	b = temp;
}
#endif

//模板技术 类型参数化 编写代码可以忽略类型
//为了让编译器区分是普通函数  模板函数
template<class T1,class T2> //template<typename T>告诉编译器 ,下面写模板函数
void MySwap(T& a, T& b){
    
    
	T temp = a;
	a = b;
	b = temp;
}

void test01(){
    
    

	int a = 30;
	int b = 20;
	//1 自动类型推导,编译器根据你传的值 进行类型自动推导
	cout << "a:" << a << " b:" << b << endl;
	MySwap(a, b); 
	cout << "a:" << a << " b:" << b << endl;

	double da = 12.3;
	double db = 21.1;
	cout << "da:" << da << " db:" << db << endl;
	MySwap(da, db);
	cout << "da:" << da << " db:" << db << endl;

	//2. 显式的指定类型
	MySwap<int>(a, b);
}

int main(void){
    
    	
	test01();
	return 0;
}

3つ、関数テンプレートと通常の関数

関数テンプレートは通常の関数と同じであり、オーバーロードすることもできます

  • C ++コンパイラは通常の関数を優先します
  • 関数テンプレートがより適切な一致を生成できる場合は、関数テンプレートを選択します
  • 空のテンプレート引数リストを介して関数テンプレートのみに一致するようにコンパイラーを制限することもできます<>
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

template<class T>
int MyAdd(T a,T b){
    
    
	return a + b;
}

//普通函数可以进行自动类型转换
//函数模板必须严格类型匹配
int MyAdd(int a,int c){
    
    
	return a + c;
}

void test01(){
    
    	
	int a = 10;
	int b = 20;
	char c1 = 'a';
	char c2 = 'b';

	MyAdd<>(a,b);//限定只使用函数模板
 
	MyAdd(a,c1);//这个调用,函数模板有更好的匹配,于是调用函数模板
	MyAdd(a, b);//普通函数int MyAdd(int a,int c)已经能完美匹配,于是调用普通函数
	MyAdd(c1,b);//这个调用,函数模板有更好的匹配,于是调用函数模板
}

//函数模板被重载
template<class T>
void Print(T a){
    
    	
    
}
template<class T>
void Print(T a , T b){
    
    
    
}

int main(void)
{
    
    
	test01();	
	return 0;
}

第四に、関数テンプレートメカニズム:

  • コンパイラは、関数テンプレートをどのタイプの関数にも処理しません
  • 関数テンプレートは、特定のタイプを通じてさまざまな関数を生成します
  • コンパイラーは、関数テンプレートを再コンパイルし、宣言の場所でテンプレートコード自体をコンパイルし、呼び出しの場所でパラメーターを置換した後にコードをコンパイルします。

おすすめ

転載: blog.csdn.net/weixin_45341339/article/details/111828814