記事ディレクトリ
1. typename の使用
テンプレート パラメーターを使用するときにクラスを使用することも、テンプレート パラメーターを定義するために typename を使用することもできます。typename に新しい役割が追加されました。
template<class container>
void Print(const container& v)
{
//编译器不确定Container::const_iterator是类型还是对象
//没有实例化的类模板,需要使用typename明确告诉编译器container是一个类型,否则编译器报错
typename container::const_iterator it = v.begin();
//也可使用auto auto it=v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
2. 非型テンプレートパラメータ
テンプレート パラメーターは、型パラメーターを非型パラメーターに分類します。
タイプ パラメータ: テンプレート パラメータ リストに表示され、その後にクラスやタイプ名などのパラメータ タイプ名が続きます。
非型パラメータ: クラス(関数)テンプレートのパラメータとして定数を使用することであり、そのパラメータはクラス(関数)テンプレート内で定数として使用できます。
例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<list>
#include<array>
using namespace std;
//静态栈
//非类型模板参数
//1.常量
//2.必须是整形,不可在类中修改
template<class T,size_t N=10>
class Stack
{
public:
void func()
{
//常量,不可修改
//N = 10;
}
private:
T _a[N];
int _top;
};
int main()
{
Stack<int, 10> st1;
Stack<int, 100> st2;
//st1.func();
//非类型模板参数使用 定长数组 C++11
//array只有一个优势,越界检查严格
array<int,10> a;
for (auto e : a)
{
cout << e << " ";
}
cout << endl;
return 0;
}
型以外のテンプレート パラメーター、配列 - 固定長配列を使用して新しいコンテナーを実装しました
3. テンプレートの特化
1.コンセプト
通常、テンプレートを使用して型に依存しないコードを実装できますが、一部の特殊な型では、誤った結果が得られる可能性があり、特別な処理が必要になります。たとえば、以下の比較に特別に使用される関数テンプレートを実装します。
namespace tzc
{
template<class T>
bool less(T a, T b)
{
return a < b;
}
}
int main()
{
int a = 10;
int b = 20;
int* c = &a;
int* d = &b;
cout << tzc::less(a, b) << endl;
cout << tzc::less(c, d) << endl; // 传入指针 ,只会比较指针
return 0;
}
2つの変数の大小を比較する関数テンプレートを実装しましたが、比較の種類が限られており、ポインタ型の変数を渡した場合、大小比較の結果が意図したものにならないことがよくあります。関数テンプレートを実装する必要があります。特殊なケースを処理するための特殊化
2. テンプレートの機能特化
関数テンプレートの特殊化手順:
1. 最初に基本的な関数テンプレートが必要です
2. キーワード テンプレートの後には空の山かっこ <> が続きます
3. 関数名の後には山括弧のペアが続きます。特殊化の必要性を指定します。 4. 関数
パラメータ テーブル: テンプレート関数の基本パラメータ タイプとまったく同じである必要があります。異なる場合、コンパイラが奇妙なエラーを報告する可能性があります。
//函数模板
template<class T>
bool Less(T left, T right)
{
return left < right;
}
//函数模板的特化 也可重载
//这种只能解决int类型的问题
template<>
bool Less<int*>(int* left, int* right)
{
return *left < *right;
}
//解决各种指针类型的比较,
template<class T>
bool Less(T* left, T* right)
{
return *left < *right;
}
int main()
{
cout << Less(1, 2) << endl;
int a = 1, b = 2;
cout << Less(&a, &b) << endl;
return 0;
}
3. クラスのテンプレートの特殊化
① 全特化
//类模板
template<class T1,class T2>
class Date
{
public:
Date() {
cout << "Date<T1 ,T2>" << endl; }
private:
T1 _d1;
T2 _d2;
};
//全特化
template<>
class Date<int ,double>
{
public:
Date() {
cout << "Date<int,double>" << endl; }
};
int main()
{
Date<int, int> d1;
Date<int, double>d2;
return 0;
}
②部分専門化
//类模板
template<class T1,class T2>
class Date
{
public:
Date() {
cout << "Date<T1 ,T2>" << endl; }
private:
T1 _d1;
T2 _d2;
};
//偏特化,特化部分参数
template<class T>
class Date<T,double>
{
public:
Date() {
cout << "Date<T,double>" << endl; }
};
//偏特化,对某些类型进行进一步特化
template<class T1,class T2>
class Date<T1*,T2*>
{
public:
Date() {
cout << "Date<T*,T*>" << endl; }
};
int main()
{
Date<double, double>d3;
Date<int*, int*>d4;
Date<double*, double*>d5;
return 0;
}