Difference between instantiation and specialization in c++ templates

前端 未结 6 853
眼角桃花
眼角桃花 2020-11-28 23:40

What is the difference between specialization and instantiation in context of C++ templates. From what I have read so far the following is what I have understood about speci

相关标签:
6条回答
  • 2020-11-29 00:09

    4 concepts:

    (implicit) instantiation: this is what you refer to as instantiation

    explicit instantiation:: this is when you tell the compiler to instantiate the template with given types, like this

    template Struct<char>; //used to control the PLACE where the template is inst-ed
    

    (explicit )specialization: this is what you refer to as specialization

    partial specialization this is when you give an alternative definition to a template for a subset of types, like this:

    template<class T> class Struct<T*> {...} //partial specialization for pointers
    
    0 讨论(0)
  • 2020-11-29 00:13

    Overview

    • Specialization: The class, function or class member you get when substituting template arguments into the template parameters of a class template or function template.

    • Instantiation: The act of creating a specialization out of a template or class template member. The specialization can be created out of a partial specialization, class template member or out of a primary class or function template.

    An explicit specialization is one that defines the class, function or member explicitly, without an instantiation.

    0 讨论(0)
  • 2020-11-29 00:20

    In c++ 11.

    instantiation:

    Instantiate the template with given template arguments

    template <typename T>
    struct test{ T m; };
    
    template test<int>;//explicit instantiation
    

    which result in a definition of a struct with a identifier test<int>

    test<int> a;//implicit instantiation
    

    if template <typename T> struct test has been instantiated with argument T = int before(explicit or implicit), then it's just a struct instantiation. Otherwise it will instantiate template <typename T> struct test with argument T = int first implicitly and then instantiate an instance of struct test<int>

    specialization:

    a specialization is still a template, you still need instantiation to get the real code.

    template <typename T>
    struct test{ T m; };
    template <> struct test<int>{ int newM; } //specialization
    

    The most useful of template specialization is probably that you can create different templates for different template arguments which means you can have different definitions of class or function for different template arguments.

    template<> struct test<char>{ int cm; }//specialization for char
    test<char> a;
    a.cm = 1;
    
    template<> struct test<long> { int lm; }//specialization for long
    test<long> a;
    a.lm = 1;
    

    In addition to these full template specializations above, there(only class template) exits partial template specialization also.

    template<typename T>
    struct test {};
    template <typename T> struct test<const T>{};//partial specialization for const T
    
    
    template <typename A, typename B>
    struct test {};
    template <typename B> struct test<int, B>{};//partial specialization for A = int
    
    0 讨论(0)
  • 2020-11-29 00:21

    A specialized template is no longer just a template. Instead, it is either an actual class or an actual function.

    A specialization is from either an instantiation or an explicit specialization, cf 14.7.4 below.

    An instantiation is based on a primary template definition. A sample implicit class template instantiation,

    template<typename T>
    class foo {}
    
    foo<int> foo_int_object;
    

    A sample explicit class template instantiation,

    template class foo<double>;
    

    An explicit specialization has a different definition from it's primary template.

    template<>
    class foo<bool> {}
    

    // extract from standard

    14 Templates

    14.7 Template instantiation and specialization

    4 An instantiated template specialization can be either implicitly instantiated (14.7.1) for a given argument list or be explicitly instantiated (14.7.2). A specialization is a class, function, or class member that is either instantiated or explicitly specialized (14.7.3).

    0 讨论(0)
  • 2020-11-29 00:33

    What is the difference between specialization and instantiation in context of C++ templates?

    Normally (no specializations present) the compiler will create instantiations of a template when they are used, by substituting actual template parameters (int in your example) for the formal template parameters (T) and then compile the resulting code.

    If a specialization is present, then for the (set of) special template parameter(s) specified by that specialization, that specialization's implementation is to be used instead of what the compiler would create.

    0 讨论(0)
  • 2020-11-29 00:35

    A template specialization actually changes the behaviour of the template for a specific type. eg convert to a string:

    template<typename T> std::string convertToString( const T& t )
    {
       std::ostringstream oss;
       oss << t;
       return oss.str();
    }
    

    Let's specialise that though when our type is already a std::string as it is pointless going through ostringstream

    template<> std::string convertToString( const std::string & t )
    {
       return t;
    }
    

    You can specialise for classes too.

    Now instantiation: this is done to allow you to move the compilation for certain types into one compilation unit. This can save you both compilation time and sometimes code-bloat too. Let's say we make the above into a class called StringConvert rather than a function.

    template<typename T>
    class StringConvert
    {
     public:
      // 4 static functions to convert from T to string, string to T,
       // T to wstring and wstring to T using streams
     };
    

    We will convert a lot of integers to strings so we can instantiate it: Put this inside one header

     extern template class StringConvert<int>;
    

    Put this inside one compilation unit:

     template class StringConvert<int>;
    

    Note that the above can also be done (without the extern in the header) with functions that are actually not implemented inline. One of your compilation units will implement them. However then your template is limited only to instantiated types. Sometimes done when the template has a virtual destructor.

    0 讨论(0)
提交回复
热议问题