1 つの記事でテンプレートを理解する

背景の紹介:
整数と浮動小数点数を加算する関数を実装したいと想像してください。C 言語に従う場合、加算を完了するには、異なる関数名を持つ 2 つの関数を記述する必要があります。C++ 言語を使用している場合は、関数のオーバーロードの機能を使用すると、同じ関数名で異なるパラメーター リストを持つ 2 つの関数を作成してタスクを完了できます。
どうしても2つの機能を実装する必要があるのでしょうか?

では、このタスクを完了するための一般的な関数を記述するだけでよいでしょうか?
次に、テンプレートが表示されるように招待する必要があります。

1. テンプレートの概念

関数テンプレートは、型に依存せず、使用時にパラメーター化される関数ファミリーを表し、実際のパラメーター型に基づいて関数の特性型バージョンを生成します。

2. 使用方法

次のメソッドを使用して関数テンプレートを定義し、必要に応じて複数のテンプレート パラメーターを定義できます。
テンプレート<クラス A、クラス B…>

template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}

3. テンプレートの原則

コンパイラーのコンパイル段階では、関数テンプレートを使用するために、コンパイラーは、渡された実際のパラメーターの型に基づいて、呼び出しに対応する関数の型を推測して生成する必要があります
たとえば、double 型と関数テンプレートを使用する場合、コンパイラは実際のパラメータを推定することにより、呼び出すための double 型関数を自動的に生成します。
ここに画像の説明を挿入します


template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}


int main()
{
    
    

	int a = 10;
	int b = 11;

	double c = 1.1;
	double d = 2.2;

	Add(a, b);
	Add(c, d);
	return 0;
}

ここに画像の説明を挿入します

上記の例からわかるように、コンパイラーは、パラメーターが異なる 2 つの関数を自動的に生成します (呼び出しアドレスが異なるため)。

4. テンプレートのインスタンス化

関数テンプレートが異なる型のパラメーターとともに使用される場合、それは関数テンプレートのインスタンス化と呼ばれます。テンプレート パラメーターのインスタンス化は、暗黙的なインスタンス化と明示的なインスタンス化に分けられます。

4.1 暗黙的なインスタンス化

実際のパラメータの型に基づいてコンパイラ自身がそれを推測させます。

template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}


int main()
{
    
    

	int a = 10;
	int b = 11;

	double c = 1.1;
	double d = 2.2;

	Add(a, b);  // 生成整形模板
	Add(c, d);   //生成double模板
	Add(a, d);   // 编译报错,因为a是int,b是double,只有一个模板T,编译器不知道生成哪个。
	// 解决方法:
	//1.用户自己来强制转化
	Add(a, (int)d);
	//2. 使用显示实例化
	return 0;
}

4.2 明示的なインスタンス化

関数名の後の <> 内にテンプレート パラメータの実際の型を指定します。

int a = 10;
double b =1.1;
Add<int>(a, b);   //显示实例化
// 如果类型不配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器会自动报错。

5. テンプレートパラメータのマッチングルール

  1. 非テンプレート パラメーターは、同じ名前の関数テンプレートと同時に存在することができ、関数テンプレートを非テンプレート関数としてインスタンス化することもできます。
// 专门处理int的加法函数
int Add(int left, int right)
{
    
    
 return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
    
    
 return left + right;
}
void Test()
{
    
    
 Add(1, 2); // 与非模板函数匹配,编译器不需要特化
 Add<int>(1, 2); // 调用编译器特化的Add版本
}
  1. 非テンプレート関数と同じ名前の関数テンプレートの場合、他のすべての条件が等しい場合、テンプレートから特殊化されたインスタンスよりも非テンプレート関数が優先して呼び出されます。テンプレートがより適切な関数を生成できる場合、テンプレートが選択されます。
// 专门处理int的加法函数
int Add(int left, int right)
{
    
    
 return left + right;
}


// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
    
    
 return left + right;
}
void Test()
{
    
    
 Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
 Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函}
  1. テンプレート関数では自動型変換はできませんが、通常の関数では自動型変換が可能です。

6. クラステンプレート

6.1 フォーマットの定義

クラス テンプレートは実際のクラスではありませんが、インスタンス化の結果が実際のクラスです。

template<class T1, class T2, ..., class Tn>
class A
{
    
    
 // 类内成员定义
};

型 A のオブジェクトをインスタンス化します。型の要件は int です。

A<int> a;
// A 类名,A<int> 才是类型

おすすめ

転載: blog.csdn.net/weixin_45153969/article/details/132914542