Managed Templates

Class templates allow you to define a type and create one or more instantiations of the type using different type parameters. For more information on standard C++ class templates, see Class Templates.

You can also create class templates from value or reference types. See Classes and Structs (Managed) for more information about creating value or reference types. However, there are some limitations to creating class templates from managed types:

  • 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.)

    // 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 may not 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++ language syntax, but 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();
    }
    
  • It is also possible to vary the managed modifier of a class from class template to partial specialization and explicit specialization.

    // 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> {};
    

Requirements

Compiler option: /clr

See Also

Concepts

Language Features for Targeting the CLR