logo

C++ のテンプレートと例

テンプレート は、C++ のシンプルでありながら非常に強力なツールです。シンプルなアイデアは、データ型をパラメーターとして渡すことで、異なるデータ型に対して同じコードを記述する必要がなくなるということです。たとえば、ソフトウェア会社では、さまざまなデータ型に対して sort() が必要になる場合があります。複数のコードを作成して維持するのではなく、1 つの sort() を作成してデータ型をパラメータとして渡すことができます。

C++ では、テンプレートをサポートするために 2 つの新しいキーワードが追加されています。 'テンプレート' そして 「タイプ名」 。 2 番目のキーワードはいつでも次のキーワードに置き換えることができます。 'クラス'



テンプレートはどのように機能するのでしょうか?

テンプレートはコンパイラ時に展開されます。これはマクロのようなものです。違いは、コンパイラがテンプレートを展開する前に型チェックを行うことです。考え方は単純で、ソース コードには関数/クラスのみが含まれますが、コンパイルされたコードには同じ関数/クラスのコピーが複数含まれる場合があります。

テンプレート-cpp

関数テンプレート

さまざまなデータ型に使用できる汎用関数を作成します。関数テンプレートの例は、sort()、max()、min()、printArray() です。

このトピックについて詳しくは、を参照してください。 C++ のジェネリックス



例:

C++
// C++ Program to demonstrate // Use of template #include  using namespace std; // One function works for all data types. This would work // even for user defined types if operator '>' はオーバーロードされたテンプレートですT myMax(T x, T y) { return (x> y) ? x : y; } int main() { // int cout に対して myMax を呼び出します<< myMax (3、7)<< endl;  // call myMax for double  cout << myMax(3.0、7.0)<< endl;  // call myMax for char  cout << myMax('g'、'e')<< endl;  return 0; }>

出力
7 7 g>

例: 実装する バブルソート C++ でのテンプレートの使用

C++
// C++ Program to implement // Bubble sort // using template function #include  using namespace std; // A template function to implement bubble sort. // We can use this for any data type that supports // comparison operator  template void bubbleSort(T a[], int n) { for (int i = 0; i< n - 1; i++)  for (int j = n - 1; i < j; j--)  if (a[j] < a[j - 1])  swap(a[j], a[j - 1]); } // Driver Code int main() {  int a[5] = { 10, 50, 30, 40, 20 };  int n = sizeof(a) / sizeof(a[0]);  // calls template function  bubbleSort (a、n);  コート<< ' Sorted array : ';  for (int i = 0; i < n; i++)  cout << a[i] << ' ';  cout << endl;  return 0; }>

出力
 Sorted array : 10 20 30 40 50>

クラステンプレート

関数テンプレートやクラス テンプレートなどのクラス テンプレートは、クラスがデータ型に依存しないものを定義する場合に便利です。 LinkedList、BinaryTree、Stack、Queue、Array などのクラスに役立ちます。



例:

C++
// C++ Program to implement // template Array class #include  using namespace std; template クラス配列 {プライベート: T* ptr;  整数サイズ; public: Array(T arr[], int s);  void print(); };テンプレート配列::Array(T arr[], int s) { ptr = 新しい T[s];  サイズ = s;  for (int i = 0; i< size; i++)  ptr[i] = arr[i]; } template 無効な配列::print() { for (int i = 0; i< size; i++)  cout << ' ' << *(ptr + i);  cout << endl; } int main() {  int arr[5] = { 1, 2, 3, 4, 5 };  Array a(arr, 5);  a.print();  0を返します。 }>>

出力
 1 2 3 4 5>

テンプレートに複数の引数を指定できますか?

はい、通常のパラメーターと同様に、複数のデータ型を引数としてテンプレートに渡すことができます。次の例は同じことを示しています。

例:

C++
// C++ Program to implement // Use of template #include  using namespace std; template クラス A { T x;  うーん。パブリック: A() { cout<< 'Constructor Called' << endl; } }; int main() {  Aa;  あ b;  0を返します。 }>>

出力
Constructor Called Constructor Called>

テンプレート引数にデフォルト値を指定できますか?

はい、通常のパラメーターと同様に、テンプレートにデフォルトの引数を指定できます。次の例は同じことを示しています。

例:

C++
// C++ Program to implement // Use of template #include  using namespace std; template クラス A { パブリック: T x;  うーん。  A() { cout<< 'Constructor Called' << endl; } }; int main() {  // This will call A  Aa;  0を返します。 }>>

出力
Constructor Called>

関数のオーバーロードとテンプレートの違いは何ですか?

関数のオーバーロードとテンプレートは両方とも、OOP のポリモーフィズム機能の例です。関数のオーバーロードは、複数の関数が非常に類似した (同一ではない) 操作を実行する場合に使用され、テンプレートは複数の関数が同一の操作を実行する場合に使用されます。

テンプレート クラス/関数に静的メンバーがある場合はどうなりますか?

テンプレートの各インスタンスには、独自の静的変数が含まれます。見る テンプレートと静的変数 詳細については。

テンプレートの特化とは何ですか?

テンプレートの特殊化により、特定のデータ型に対して異なるコードを使用できるようになります。見る テンプレートの特化 詳細については。

型以外のパラメータをテンプレートに渡すことはできますか?

型以外の引数をテンプレートに渡すことができます。非型パラメータは主に、テンプレートの特定のインスタンスの最大値または最小値、またはその他の定数値を指定するために使用されます。非型パラメーターについて注意すべき重要な点は、それらが const である必要があるということです。コンパイラは、コンパイル時に非型パラメータの値を認識している必要があります。コンパイラはコンパイル時に指定された非型値の関数/クラスを作成する必要があるためです。以下のプログラムで、10000 または 25 を変数に置き換えると、コンパイル エラーが発生します。

例:

C++
// C++ program to demonstrate // working of non-type parameters // to templates in C++ #include  using namespace std; template int arrMin(T arr[], int n) { int m = max;  for (int i = 0; i< n; i++)  if (arr[i] < m)  m = arr[i];  return m; } int main() {  int arr1[] = { 10, 20, 15, 12 };  int n1 = sizeof(arr1) / sizeof(arr1[0]);  char arr2[] = { 1, 2, 3 };  int n2 = sizeof(arr2) / sizeof(arr2[0]);  // Second template parameter  // to arrMin must be a  // constant  cout << arrMin (arr1, n1)<< endl;  cout << arrMin(arr2, n2);    0を返します。 }>>

出力
10 1>

以下は、コンストラクターとテンプレートを使用してさまざまなデータ型を表示する C++ プログラムの例です。いくつかのアクションを実行します

  • main() 関数でオブジェクトを作成して文字値を渡します。
  • main() 関数でオブジェクトを作成して整数値を渡します。
  • main() 関数でオブジェクトを作成して float 値を渡します。

例:

C++
// C++ program to show different data types using a // constructor and template. #include  using namespace std; // defining a class template template class info { public: // テンプレート型 info(TA) のコンストラクタ { cout<< '
'  << 'A = ' << A  << ' size of data in bytes:' << sizeof(A);  }  // end of info() }; // end of class // Main Function int main() {  // clrscr();  // passing character value by creating an objects  infop('x');  // オブジェクト情報を作成して整数値を渡します q(22);  // オブジェクト情報を作成して float 値を渡すr(2.25);  0を返します。 }>>

出力
A = x size of data in bytes:1 A = 22 size of data in bytes:4 A = 2.25 size of data in bytes:4>

テンプレート引数の推定

テンプレート引数の推定では、クラスまたは関数テンプレートに渡される引数のデータ型を自動的に推定します。これにより、データ型を明示的に指定せずにテンプレートをインスタンス化できます。

Eclipse上のjavafx

たとえば、2 つの数値を乗算する次の関数テンプレートを考えてみましょう。

template  t multiply (t num1,t num2) { return num1*num2; }>

一般に、整数に対して multiply() 関数を使用したい場合は、次のように呼び出す必要があります。

multiply (25, 5);>

しかし、次のように呼ぶこともできます。

multiply(23, 5);>

型を明示的に指定しません。つまり、1、3 は整数です。

テンプレート クラスにも同じことが当てはまります (C++17 以降のみ)。テンプレート クラスを次のように定義するとします。

template class student{  private:  t total_marks;  public:  student(t x) : total_marks(x) {} };>

このクラスのインスタンスを作成する場合は、次のいずれかの構文を使用できます。

student stu1(23);    or  student stu2(24);>

注記: クラスのテンプレート引数推定は C++17 以降でのみ利用可能であるため、以前のバージョンでクラスの自動テンプレート引数推定を使用しようとすると、エラーがスローされることに注意することが重要です。

テンプレート引数の推定の例

以下の例は、STL ベクトル クラス テンプレートが明示的に指定されずにデータ型を推定する方法を示しています。

C++
// C++ Program to illustrate template arguments deduction in // STL #include  #include  using namespace std; int main() {  // creating a vector object without specifying  // type  vector v1{ 1.1, 2.0, 3.9, 4.909 };  cout << 'Elements of v1 : ';  for (auto i : v1) {  cout << i << ' ';  }  // creating a vector object without specifying type  vector v2{ 1, 2, 3, 4 };  cout << endl << 'Elements of v2 : ';  for (auto i : v2) {  cout << i << ' ';  } }>


出力

Elements of v1 : 1.1 2 3.9 4.909  Elements of v2 : 1 2 3 4>

注記: C++17 ではクラス テンプレート引数の推定が追加されたため、上記のプログラムは C++14 以下のコンパイラではコンパイルに失敗します。

関数テンプレートの引数の推定

関数テンプレートの引数推定は、C++98 標準以降、C++ の一部となっています。関数テンプレートに渡す引数の型の宣言を省略でき、コンパイラは関数呼び出しで渡した引数を使用して型を自動的に推測します。

例: 次の例では、C++ の関数がそれ自体で型を自動的に推定する方法を示します。

C++
// C++ program to illustrate the function template argument // deduction #include  using namespace std; // defining function template template t multiply(t first, t Second) { return first * Second; } // ドライバーコード int main() { auto result = multiply(10, 20);  std::cout<< 'Multiplication OF 10 and 20: ' << result  << std::endl;  return 0; }>

出力
Multiplication OF 10 and 20: 200>

注記: template void function(t a1, t a2){} のように引数の型が同じ関数テンプレートの場合、異なる型の引数を渡すことはできません。

クラス テンプレートの引数の推定 (C++17 以降)

クラス テンプレートの引数推定は C++17 で追加され、それ以来言語の一部となっています。これにより、関数テンプレートと同様に型を明示的に定義せずにクラス テンプレート インスタンスを作成できます。

例: 次の例では、コンパイラが C++ でテンプレートを自動的にクラス化する方法を示します。

C++
// C++ Program to implement Class Template Arguments // Deduction #include  #include  #include  using namespace std; // Defining class template template クラス学生 { プライベート: 文字列学生名;  T total_marks; public: // パラメータ化されたコンストラクター Student(string n, T m) :student_name(n) , total_marks(m) { } void getinfo() { // Student cout の詳細を出力します<< 'STUDENT NAME: ' << student_name << endl;  cout << 'TOTAL MARKS: ' << total_marks << endl;  cout << 'Type ID: ' << typeid(total_marks).name()  << endl;  } }; int main() {  student s1('Vipul', 100); // Deduces student  student s2('Yash', 98.5); // Deduces student  s1.getinfo();  s2.getinfo();  return 0; }>


出力

STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>

ここで、i は int を意味し、d は double を意味します。

テンプレートのメタプログラミングの場合、r 次の記事を参照してください – テンプレートのメタプログラミング

取ってください テンプレートに関するクイズ 。 Java はこれらの機能もサポートしています。 Java はそれを呼びます ジェネリック医薬品