Visual Studio 2005 引入 CLR 泛型,C++/CLI 同時支援 CLR 泛型與 C++ 模板。本文詳細對比兩者在參數列表、類型約束、非類型參數、預設值、模板模板參數等方面的異同。
Object 或其衍生類型,操作受限。可透過 where 子句指定基類/介面約束。C++ 模板支援非類型參數(整數、指標、參考),CLR 泛型不支援。
// C++ 模板:固定大小堆疊
template <class ElemType, int Size>
ref class FixedStack { array<ElemType>^ data; ... };
C++ 模板支援預設值,CLR 泛型不支援。
template <class T, int Size = 1024> ref class Buffer {};
Buffer<String^> b1; // 使用預設 1024
Buffer<String^, 512> b2; // 覆寫大小
C++ 模板支援模板作為參數,CLR 泛型不支援。
template <template <class> class Arena, class T>
class Editor { Arena<T> arena; };
Editor<Vector, int> ed;
C++ 模板允許函數/物件位址作為非類型參數(編譯期常數)。
typedef void (*Handler)(...);
template <class T, int Size, Handler Callback>
class Stack {};
| 特性 | C++ 模板 | CLR 泛型 |
|---|---|---|
| 類型約束 | 無(鴨子類型) | 隱含 Object,可擴展 |
| 非類型參數 | 支援 | 不支援 |
| 預設參數值 | 支援 | 不支援 |
| 模板模板參數 | 支援 | 不支援 |
| 實例化機制 | 編譯期展開 | 執行期 JIT |
| 程式碼膨脹 | 可能 | 共享實作 |
選擇建議:需極致效能、非類型參數、模板元編程用 C++ 模板;需跨語言互操作、執行期類型安全、減少程式碼膨脹用 CLR 泛型。