Typy ogólne i szablony (C++/CLI)
Typy ogólne i szablony to funkcje języka, które zapewniają obsługę typów sparametryzowanych. Są one jednak różne i mają różne zastosowania. Ten temat zawiera omówienie wielu różnic.
Aby uzyskać więcej informacji, zobacz środowisko wykonawcze systemu Windows i szablony zarządzane.
Porównywanie szablonów i typów ogólnych
Kluczowe różnice między szablonami ogólnymi i C++:
Typy ogólne są ogólne, dopóki typy nie zostaną zastąpione w czasie wykonywania. Szablony są wyspecjalizowane w czasie kompilacji, więc nie są one nadal sparametryzowane typy w czasie wykonywania
Środowisko uruchomieniowe języka wspólnego obsługuje specjalnie typy ogólne w języku MSIL. Ponieważ środowisko uruchomieniowe wie o rodzajach ogólnych, określone typy mogą zostać zastąpione typami ogólnymi podczas odwoływania się do zestawu zawierającego typ ogólny. Natomiast szablony są rozpoznawane jako zwykłe typy w czasie kompilacji, a wynikowe typy mogą nie być wyspecjalizowane w innych zestawach.
Typy ogólne wyspecjalizowane w dwóch różnych zestawach z tego samego typu argumentami są tego samego typu. Szablony wyspecjalizowane w dwóch różnych zestawach o tym samym typie argumenty są uznawane przez środowisko uruchomieniowe za różne typy.
Typy ogólne są generowane jako pojedynczy fragment kodu wykonywalnego, który jest używany dla wszystkich argumentów typu odwołania (nie dotyczy to typów wartości, które mają unikatową implementację na typ wartości). Kompilator JIT wie o rodzajach ogólnych i jest w stanie zoptymalizować kod dla typów odwołań lub wartości, które są używane jako argumenty typu. Szablony generują oddzielny kod środowiska uruchomieniowego dla każdej specjalizacji.
Typy ogólne nie zezwalają na parametry szablonu innego niż typ, takie jak
template <int i> C {}
. Szablony zezwalają na nie.Typy ogólne nie zezwalają na jawną specjalizację (czyli niestandardową implementację szablonu dla określonego typu). Szablony do wykonania.
Typy ogólne nie zezwalają na częściową specjalizację (implementacja niestandardowa dla podzestawu argumentów typu). Szablony do wykonania.
Typy ogólne nie zezwalają na użycie parametru typu jako klasy bazowej dla typu ogólnego. Szablony do wykonania.
Szablony obsługują parametry szablonu (np.
template<template<class T> class X> class MyClass
), ale typy ogólne nie.
Łączenie szablonów i typów ogólnych
Podstawowa różnica w rodzajach ogólnych ma wpływ na tworzenie aplikacji łączących szablony i typy ogólne. Załóżmy na przykład, że masz klasę szablonu, dla której chcesz utworzyć ogólną otokę, aby udostępnić ten szablon innym językach jako ogólny. Nie można mieć ogólnego parametru typu, który następnie przekazuje do szablonu, ponieważ szablon musi mieć ten parametr typu w czasie kompilacji, ale ogólny nie rozwiąże parametru typu do czasu wykonania. Zagnieżdżanie szablonu wewnątrz typu ogólnego nie będzie działać, ponieważ nie ma możliwości rozszerzenia szablonów w czasie kompilacji dla dowolnych typów ogólnych, które mogą zostać utworzone w czasie wykonywania.
Przykład
opis
W poniższym przykładzie przedstawiono prosty przykład użycia szablonów i typów ogólnych. W tym przykładzie klasa szablonu przekazuje swój parametr do typu ogólnego. Odwrotnie nie jest możliwe.
Ten idiom może być używany, gdy chcesz utworzyć istniejący ogólny interfejs API z kodem szablonu lokalnym dla zestawu języka C++/interfejsu wiersza polecenia lub gdy trzeba dodać dodatkową warstwę parametryzacji do typu ogólnego, aby skorzystać z niektórych funkcji szablonów, które nie są obsługiwane przez typy ogólne.
Kod
// 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