Windows Runtime and Managed Templates (C++/CLI and C++/CX)
Templates enable you to define a prototype of a Windows Runtime or common language runtime type, and then instantiate variations of that type by using different template type parameters.
All Runtimes
You can create templates from value or reference types. For more information about creating value or reference types, see Classes and Structs.
For more information about standard C++ class templates, see Class Templates.
Windows Runtime
(There are no remarks for this language feature that apply to only the Windows Runtime.)
Requirements
Compiler option: /ZW
Common Language Runtime
There are some limitations to creating class templates from managed types, which are demonstrated in the following code examples.
Requirements
Compiler option: /clr
Examples
It is possible to instantiate a generic type with a managed type template parameter, but you cannot instantiate a managed template with a generic type template parameter. This is because generic types are resolved at runtime. For more information, see Generics and Templates (C++/CLI).
// managed_templates.cpp
// compile with: /clr /c
generic<class T>
ref class R;
template<class T>
ref class Z {
// Instantiate a generic with a template parameter.
R<T>^ r; // OK
};
generic<class T>
ref class R {
// Cannot instantiate a template with a generic parameter.
Z<T>^ z; // C3231
};
A generic type or function cannot be nested in a managed template.
// managed_templates_2.cpp
// compile with: /clr /c
template<class T> public ref class R {
generic<class T> ref class W {}; // C2959
};
You cannot access templates defined in a referenced assembly with C++/CLI language syntax, but you can use reflection. If a template is not instantiated, it's not emitted in the metadata. If a template is instantiated, only referenced member functions will appear in metadata.
// managed_templates_3.cpp
// compile with: /clr
// Will not appear in metadata.
template<class T> public ref class A {};
// Will appear in metadata as a specialized type.
template<class T> public ref class R {
public:
// Test is referenced, will appear in metadata
void Test() {}
// Test2 is not referenced, will not appear in metadata
void Test2() {}
};
// Will appear in metadata.
generic<class T> public ref class G { };
public ref class S { };
int main() {
R<int>^ r = gcnew R<int>;
r->Test();
}
You can change the managed modifier of a class in a partial specialization or explicit specialization of a class template.
// managed_templates_4.cpp
// compile with: /clr /c
// class template
// ref class
template <class T>
ref class A {};
// partial template specialization
// value type
template <class T>
value class A <T *> {};
// partial template specialization
// interface
template <class T>
interface class A<T%> {};
// explicit template specialization
// native class
template <>
class A <int> {};