泛型和模板 (Visual C++)
型和模板是提供参数化支持类型的两个语言功能。 但是,它们是不同且具有不同的使用。 本主题提供了许多不同的概述。
有关更多信息,请参见Windows 运行时和托管模板(C++ 组件扩展)和 模板概述。
比较模板和泛型
泛型和 C++ 模板之间的主要差异:
泛型是泛型的,直到类型已经被替换在运行时。 模板专用化在编译时,因此它们不是仍然参数化类型在运行时
公共语言运行时专门支持在 MSIL 的一般。 由于运行时知道泛型,特定类型可带有泛型类型将替换,当引用包含泛型类型时的程序集。 模板,相反,解析为普通类型在编译时,得到的类型不能专用其他程序集。
具有同一类型的参数两个不同的程序集专用的一般是同一类型。 具有同一类型的参数两个不同的程序集专用模板在运行时视为不同的类型。
泛型,便会产生用作所有可执行代码的单个引用类型参数 (这不适用值类型,具有单个实现每个值类型)。 JIT 编译器知道用作类型参数的泛型并且可以优化引用或值类型的代码。 模板生成每个专用化的单独运行时代码。
一般不允许非类型模板参数,如 template <int i> C {}。 模板将它们。
一般不允许显式专用化 (即自定义实现特定类型的模板)。 模板。
一般不允许部分专用化 (类型参数) 的子集的自定义实现。 模板。
一般不允许该类型参数用作基类为泛型类型。 模板。
模板支持模板模板参数 (即。 template<template<class T> class X> class MyClass),但是,一般不。
合并模板和泛型
- 在普通上的基本差异将模板与普通编译的应用程序的影响。 例如,假设有模板类要创建一个一般包装用于显示该模板在其他语言为泛型。 您不能具有泛型使然后通过传递给模板的类型参数,,因为模板需要对该类型参数在编译时,但是,一般不会解析类型参数在运行时中。 嵌套在泛型中的模板不起作用,因为无法展开模板在编译时无法实例化在运行时的任意泛型类型的。
示例
说明
下面的示例同时显示了一个简单的示例模板和泛型。 在此示例中,模板类通过其参数传递给泛型类型。 反转是不可能的。
可以使用这个,当您使用在本地。 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);
}
Output
F