C++汎用プログラミングとテンプレート
3906 ワード
目次
一.汎用プログラミング
二.関数テンプレート
2.1関数テンプレート形式
2.2関数テンプレートの原理
2.3関数テンプレートのインスタンス化
2.4テンプレートパラメータの整合原則
一時変数、参照パラメータ、constについてのブログ
三.クラステンプレート
3.1クラステンプレートの定義形式
3.2クラステンプレートのインスタンス化
一.汎用プログラミング
同じ関数を使用して異なるパラメータタイプを処理する場合、関数リロードを使用してこの機能を実現できます.
関数のリロードは便利ですが、関数のリロードにも悪い点がある可能性があります.リロード関数はタイプが異なるだけで、コードの多重化率は比較的低く、新しいタイプが現れる限り、対応する関数 を増やす必要がある.コードの保守性は比較的低く、1つのエラーですべてのリロードエラーが発生する可能性があります 関数のリロードにいくつかの欠点がある以上、修正する方法はありませんか.先輩たちはこの問題を解決したに違いありません.この時、汎用プログラミングがあります.
汎用プログラミング:タイプに関係のない汎用コードを記述することは、コード多重化の手段である.テンプレートは汎用プログラミングの基礎です.
二.関数テンプレート
関数テンプレートは、タイプに関係なくパラメータ化され、実パラメータタイプに基づいて関数の特定のタイプバージョンを生成する関数ファミリーを表します.
2.1関数テンプレート形式
template
戻り値タイプ関数名(パラメータリスト){}
注意:typenameはテンプレートパラメータを定義するためのキーワードであり、classを使用することもできます(classの代わりにstructを使用することはできません)
2.2関数テンプレートの原理
テンプレートは青写真で、それ自体が関数ではないことを覚えておいてください.コンパイラがこのテンプレートを使用して特定のタイプの関数を生成します.テンプレートとは、私たちがやるべきことをコンパイラに繰り返すことです.
コンパイルフェーズでは、コンパイラは、入力された実パラメータタイプに基づいて、呼び出しのために対応するタイプの関数をプッシュします.
例:
このとき、呼び出し関数が入力されたパラメータが2つのintタイプのデータである場合、コンパイラはintタイプの交換関数をプッシュします.
呼び出し関数が2つのdoubleタイプのデータである場合、コンパイラはdoubleタイプの交換関数をプッシュします.
もちろんcharタイプも可能です.呼び出された関数が異なります
2.3関数テンプレートのインスタンス化
異なるタイプのパラメータで関数テンプレートを使用する場合、関数テンプレートのインスタンス化と呼ばれます.
①暗黙的なインスタンス化:コンパイラにテンプレートパラメータの実際のタイプを実参に基づいて推論させる
しかし、伝達されるパラメータがintタイプ、doubleタイプであれば、偽入の2つのパラメータのタイプが異なる場合、コンパイラはどのように処理しますか?このような場合、コンパイラは、Tが1つしかないため、Tをintにプッシュしたり、Tをdoubleにプッシュしたりしているとは確信できないため、エラーを報告します.
テンプレートでは、コンパイラは一般的にタイプ変換操作を行いません.変換に問題が発生すると、コンパイラは鍋を背負います.
上記の問題を解決するには、次の2つの方法があります.ユーザ自身がタイプ変換 を強制する.明示的インスタンス化 を使用
②明示的なインスタンス化:関数名の後の<>にテンプレートパラメータの実際のタイプを指定し、関数の戻り値は推論に参加できず、形パラメータのみ
タイプが一致しない場合、コンパイラは暗黙的なタイプ変換を試み、変換に成功しない場合、コンパイラはエラーを報告します.
2.4テンプレートパラメータの整合原則非テンプレート関数は、同じ名前の関数テンプレートと同時に存在することができ、この非テンプレート関数 としてインスタンス化することもできる.非親関数および同名関数テンプレートの場合、他の条件が同じである場合、テンプレートからインスタンスを生成することなく、異動時に非テンプレート関数が優先的に呼び出されます.テンプレートがよりよく一致する関数を生成できる場合は、テンプレートを選択します.
一時変数、参照パラメータ、constについてのブログ
https://blog.csdn.net/qq_41209741/article/details/84255449
三.クラステンプレート
3.1クラステンプレートの定義形式
3.2クラステンプレートのインスタンス化
クラステンプレートのインスタンス化には、クラステンプレート名の後に<>を付け、インスタンス化のタイプを<>に配置する必要があります.クラステンプレート名は真のクラスではなく、インスタンス化の結果こそ真のクラスです.
メンバー変数がプライベートで直接アクセスできないため、自己実装のシーケンステーブルにアクセスできます.関数Print、リロード入力および出力、リロード[]を提供できます.
クラステンプレートメンバー関数の分離定義:
テンプレートクラス名:Date Vector
テンプレートクラスタイプ:Date Vector
一.汎用プログラミング
二.関数テンプレート
2.1関数テンプレート形式
2.2関数テンプレートの原理
2.3関数テンプレートのインスタンス化
2.4テンプレートパラメータの整合原則
一時変数、参照パラメータ、constについてのブログ
三.クラステンプレート
3.1クラステンプレートの定義形式
3.2クラステンプレートのインスタンス化
一.汎用プログラミング
同じ関数を使用して異なるパラメータタイプを処理する場合、関数リロードを使用してこの機能を実現できます.
関数のリロードは便利ですが、関数のリロードにも悪い点がある可能性があります.
汎用プログラミング:タイプに関係のない汎用コードを記述することは、コード多重化の手段である.テンプレートは汎用プログラミングの基礎です.
二.関数テンプレート
関数テンプレートは、タイプに関係なくパラメータ化され、実パラメータタイプに基づいて関数の特定のタイプバージョンを生成する関数ファミリーを表します.
2.1関数テンプレート形式
template
戻り値タイプ関数名(パラメータリスト){}
template
T Add(T s1, T s2)
{
return s1 + s2;
}
注意:typenameはテンプレートパラメータを定義するためのキーワードであり、classを使用することもできます(classの代わりにstructを使用することはできません)
2.2関数テンプレートの原理
テンプレートは青写真で、それ自体が関数ではないことを覚えておいてください.コンパイラがこのテンプレートを使用して特定のタイプの関数を生成します.テンプレートとは、私たちがやるべきことをコンパイラに繰り返すことです.
コンパイルフェーズでは、コンパイラは、入力された実パラメータタイプに基づいて、呼び出しのために対応するタイプの関数をプッシュします.
例:
template
void Swap(T& s1, T& s2)//
{
T tmp = s1;
s1 = s2;
s2 = tmp;
}
このとき、呼び出し関数が入力されたパラメータが2つのintタイプのデータである場合、コンパイラはintタイプの交換関数をプッシュします.
int s1 = 1;
int s2 = 2;
Swap(s1,s2);
呼び出し関数が2つのdoubleタイプのデータである場合、コンパイラはdoubleタイプの交換関数をプッシュします.
double s3 = 1.01;
double s4 = 2.02;
Swap(s3,s4);
もちろんcharタイプも可能です.呼び出された関数が異なります
2.3関数テンプレートのインスタンス化
異なるタイプのパラメータで関数テンプレートを使用する場合、関数テンプレートのインスタンス化と呼ばれます.
①暗黙的なインスタンス化:コンパイラにテンプレートパラメータの実際のタイプを実参に基づいて推論させる
template
T Add(T s1, T s2)
{
return s1 + s2;
}
void TestAdd()
{
int s1 = 1;
int s2 = 2;
double s3 = 1.01;
double s4 = 2.02;
Add(s1, s2);
Add(s1, (int)s3);//
}
しかし、伝達されるパラメータがintタイプ、doubleタイプであれば、偽入の2つのパラメータのタイプが異なる場合、コンパイラはどのように処理しますか?このような場合、コンパイラは、Tが1つしかないため、Tをintにプッシュしたり、Tをdoubleにプッシュしたりしているとは確信できないため、エラーを報告します.
テンプレートでは、コンパイラは一般的にタイプ変換操作を行いません.変換に問題が発生すると、コンパイラは鍋を背負います.
上記の問題を解決するには、次の2つの方法があります.
②明示的なインスタンス化:関数名の後の<>にテンプレートパラメータの実際のタイプを指定し、関数の戻り値は推論に参加できず、形パラメータのみ
Add(s1, s3);
タイプが一致しない場合、コンパイラは暗黙的なタイプ変換を試み、変換に成功しない場合、コンパイラはエラーを報告します.
2.4テンプレートパラメータの整合原則
int Add(int s1, int s2)
{
return s1 + s2;
}
template
T1 Add(T1 s1, T2 s2)
{
return s1 + s2;
}
void TestAdd()
{
int s1 = 1;
int s2 = 2;
double s3 = 1.01;
double s4 = 2.02;
Add(s1, s2);//
Add(s1,s2);//
Add(s1, s4);//
Add(s3, s4);//
}
一時変数、参照パラメータ、constについてのブログ
https://blog.csdn.net/qq_41209741/article/details/84255449
三.クラステンプレート
3.1クラステンプレートの定義形式
template
class
{
//
};
3.2クラステンプレートのインスタンス化
クラステンプレートのインスタンス化には、クラステンプレート名の後に<>を付け、インスタンス化のタイプを<>に配置する必要があります.クラステンプレート名は真のクラスではなく、インスタンス化の結果こそ真のクラスです.
メンバー変数がプライベートで直接アクセスできないため、自己実装のシーケンステーブルにアクセスできます.関数Print、リロード入力および出力、リロード[]を提供できます.
T& operator[](size_t pos)
{
return _a[pos];
}
size_t Size()
{
return _size;
}
クラステンプレートメンバー関数の分離定義:
Vector();
.
.
.
template
Vector::Vector()
:_a(nuulptr)
,_capacity(0)
,_size(0)
{}
テンプレートクラス名:Date Vector
テンプレートクラスタイプ:Date Vector