ジェネリックとテンプレート (Visual C++)
ジェネリックとテンプレートは、パラメーター化された型をサポートできる両方の言語機能です。ただし、異なるため、さまざまな用途があります。このトピックでは、多くの違いの概要を説明します。
詳細については、「Windows ランタイムおよびマネージ テンプレート (C++ コンポーネント拡張)」および「テンプレートの概要」を参照してください。
テンプレートおよびジェネリックの比較
ジェネリックと C++ テンプレートの重要な違い:
はジェネリック型がランタイムでの代わりになるまで一般的です。テンプレートはコンパイル時に特化するため、ランタイムにパラメーター化された型ではありません。
共通言語ランタイムは、 MSIL のジェネリックをサポートします。ランタイムがジェネリックを認識するため、特定の型はジェネリック型を含むアセンブリを参照する場合、ジェネリック型の代わりに使用できます。テンプレートは、これに対し、コンパイル時に通常の型に解決され、結果の型は他のアセンブリを特化されることがあります。
同じ型引数を持つ 2 人の異なるアセンブリを特化するジェネリック型は同じです。同じ型引数を持つ 2 人の異なるアセンブリを特化したテンプレートは、ランタイムによって異なる型と見なされます。
ジェネリックはすべての参照型の引数に使用される実行可能コードの単一の部分として生成されます。これは、値型ごとに一意の実装がある値型についてもありません。JIT コンパイラは型引数として使用されるジェネリックについて確認し、参照型または値型のコードを最適化できます。テンプレートは、各特化の別のランタイム コードを生成します。
ジェネリックは template <int i> C {}のような非型テンプレート パラメーターを、使用できません。テンプレートは、ができます。
ジェネリックは明示的な特殊化 (つまり、特定の種類のテンプレートのカスタム実装)を使用できません。テンプレートは。
ジェネリックは、部分的な特化 (型引数のサブセットのカスタム実装)を使用できません。テンプレートは。
はジェネリック型パラメーターをジェネリック型の基本クラスとして使用することはできません。テンプレートは。
テンプレートがサポートするテンプレート テンプレート パラメーター (たとえば。template<template<class T> class X> class MyClass)が、ジェネリックは。
テンプレートおよびジェネリックの結合
- ジェネリックの基本的な違いにテンプレートとジェネリックを組み合わせたアプリケーションの構築に影響があります。たとえば、ジェネリックとして他の言語にそのテンプレートを公開するための汎用ラッパーを作成するテンプレート クラスがあるとします。テンプレートはコンパイル時に型パラメーターを持つ必要があるジェネリックは、ランタイムの型パラメーターは解決されませんので、一般的には、パスがテンプレートに型パラメーターを取得することはできません。ジェネリック内のテンプレートを入れ子にすることはランタイムにインスタンスを作成できる任意のジェネリック型のコンパイル時にテンプレートを配置できないため、機能しません。
例
Description
次の例は、テンプレートとジェネリックを一緒に使用する簡単な例を次に示します。この例では、テンプレート クラスは、ジェネリック型パラメーターにを渡します。反転はできません。
この表現はジェネリック型にパラメーター化の追加のレイヤーを追加する必要があるときに Visual C++ のアセンブリに対してローカルであるか、ジェネリックでサポートされていないテンプレートの特定の機能を利用するには、テンプレート コードの既存の一般的な API でビルドする場合に使用できます。
コード
// templates_and_generics.cpp
// compile with: /clr
using namespace System;
generic <class ItemType>
ref class MyGeneric {
ItemType m_item;
public:
MyGeneric(ItemType item) : m_item(item) {}
void F() {
Console::WriteLine("F");
}
};
template <class T>
public ref class MyRef {
MyGeneric<T>^ ig;
public:
MyRef(T t) {
ig = gcnew MyGeneric<T>(t);
ig->F();
}
};
int main() {
// instantiate the template
MyRef<int>^ mref = gcnew MyRef<int>(11);
}
出力
F