C++のテンプレートとJavaのジェネリック
テンプレートはジェネリックプログラミングの基盤であり、特定のタイプに依存しない方法でコードを記述します。
テンプレートは、ジェネリッククラスまたは関数を作成するための青写真または式です。イテレータやアルゴリズムなどのライブラリコンテナはジェネリックプログラミングの例であり、テンプレートの概念を使用して開発されています。
ベクトルなど、各コンテナの定義は1つですが、ベクトル
サンプルコード
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
} 出力
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
一方、ジェネリックスとしてのJava。
Javaジェネリックメソッドとジェネリッククラスを使用すると、プログラマーは、単一のメソッド宣言で関連するメソッドのセットを指定するか、単一のクラス宣言で関連するタイプのセットをそれぞれ指定できます。
ジェネリックスは、プログラマーがコンパイル時に無効な型をキャッチできるようにするコンパイル時の型の安全性も提供します。
Java Genericの概念を使用して、オブジェクトの配列を並べ替える一般的なメソッドを記述してから、整数配列、二重配列、文字列配列などを使用して一般的なメソッドを呼び出し、配列要素を並べ替えることができます。
ジェネリックメソッド
さまざまなタイプの引数を使用して呼び出すことができる単一のジェネリックメソッド宣言を記述できます。ジェネリックメソッドに渡される引数のタイプに基づいて、コンパイラは各メソッド呼び出しを適切に処理します。ジェネリックメソッドを定義するためのルールは次のとおりです-
-
すべてのジェネリックメソッド宣言には、メソッドの戻り型(次の例では
)の前に山かっこ(<および>)で区切られた型パラメーターセクションがあります。 -
各タイプパラメータセクションには、コンマで区切られた1つ以上のタイプパラメータが含まれています。型変数とも呼ばれる型パラメーターは、ジェネリック型名を指定する識別子です。
-
型パラメーターを使用して、戻り型を宣言し、実際の型引数と呼ばれる、汎用メソッドに渡される引数の型のプレースホルダーとして機能できます。
-
ジェネリックメソッドの本体は、他のメソッドと同じように宣言されます。型パラメーターは、プリミティブ型(int、double、charなど)ではなく、参照型のみを表すことができることに注意してください。
サンプルコード
public class GenericMethodTest {
// generic method printArray
public static < E > void printArray( E[] inputArray ) {
// Display array elements
for(E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
public static void main(String args[]) {
// Create arrays of Integer, Double and Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println("Array integerArray contains:");
printArray(intArray); // pass an Integer array
System.out.println("\nArray doubleArray contains:");
printArray(doubleArray); // pass a Double array
System.out.println("\nArray characterArray contains:");
printArray(charArray); // pass a Character array
}
} 出力
Array integerArray contains: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
次に、テンプレートとジェネリックの違いを見てみましょう。違いは以下のようなものです-
-
型消去を使用します。これにより、コンパイル時の型チェックがより厳密になります。 JavaのGenericsは、コンパイル時の安全性を提供し、型キャストの必要性を排除します。これは、このタイプの消去が確実に行われるように、Javaコンパイラのフロントエンドに直接存在します。
-
C ++では、テンプレートが使用されている場合、コンパイラは、テンプレート内のジェネリックパラメータを指定されたタイプに置き換えた後、テンプレートコードを再度発行します。
-
Javaでは、任意のオブジェクトを使用して関数を呼び出すデータ型を指定する必要がある場合でも、必要な処理を行うラッパークラスではなく、実際のデータ型を使用したC++のように型キャストする必要はありません。
-
Javaジェネリックは、初期化時に型チェックを使用し、非ジェネリックコードと同等のバイトコードを生成します。C++には「ラタンタイピング」とテンプレートメタプログラミングがあり、インスタンス化ごとに新しいクラスを生成します。
-
C#ジェネリックとC++テンプレート
C#ジェネリックおよびC ++テンプレートは、パラメーター化された型のサポートを提供します。違いは次のとおりです- 柔軟性 C ++テンプレートは、C#ジェネリックよりも柔軟性があります 明示的な特殊化 明示的な特殊化はC#ではサポートされていません タイプパラメータ typeパラメーターは、C#のジェネリック型の基本クラスとして使用できません C#では、型パラメーターにデフォルトの型を設定することはできません。 ランタイム C ++テンプレートにはコンパイル時のモーダルがありますが、C#Genericsはコンパイル時と実行時の両方です。ジェネリックはランタイムをサポートしています。
-
Javaで型消去
ジェネリックプログラミングをサポートし、より厳密な型チェックを実行するために、Javaは型消去を実装しています。 ジェネリック型のすべての型パラメーターは、バウンド(非バウンドの場合)またはオブジェクトタイプに置き換えられます。このように、バイトコードにはクラス、メソッド、およびインターフェースのみが含まれます。 型を保持するための型キャスト。 ブリッジメソッドは、拡張ジェネリック型のポリモーフィズムの概念を維持するために生成されます。 例 import java.io.PrintStream; import java.util.*; public class Demo{