54

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 specialization and instantiation.

template <typename T>
struct Struct
{

     T x;
};

template<>
struct Struct <int> //specialization
{

    //code
};

int main()
{
   Struct <int> s; //specialized version comes into play
   Struct <float> r; // Struct <float> is instantiated by the compiler as shown below

}

Instantiation of Struct <float> by the compiler

template <typename T=float>
struct Struct
{
    float x;
}

Is my understanding of template instantiation and specialization correct?

Dr. Xperience
  • 475
  • 1
  • 5
  • 18
Saurabh29729
  • 541
  • 1
  • 4
  • 3

6 Answers6

59

(Implicit) Instantiation

This is what you refer to as instantiation (as mentioned in the Question)

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 (as mentioned in the Question)

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
Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 9
    And in the C++ standard (but nowhere else) there's also implicit specialization, which is what the compiler does when you instantiate a template and no explicit specialization is selected. – Sebastian Redl Apr 18 '13 at 12:39
  • @Redl Citations concerning what you said are highly recommended, if you have some. – Gab是好人 Apr 12 '17 at 18:52
  • 1
    Your answer was very helpful; I'd also like to mention https://stackoverflow.com/a/2351155/1043529 -- there are caveats regarding shared libraries because, as I understand it, an 'unused' instantiation in one is stripped while another referencing the instantiation trusts that it will be resolved at some point during linkage. The result is a fairly misleading 'undefined reference' unless you do your instantiations in headers. I took that error to mean that I had to provide every explicit specialization! – John P Jul 27 '17 at 13:24
23

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.

sbi
  • 219,715
  • 46
  • 258
  • 445
14

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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Would that be [class template] member, or class [template member]? – Dan Nissenbaum Dec 15 '14 at 17:51
  • Also - perhaps - beneath the full answer as given, you could append two additional bullet points with examples. – Dan Nissenbaum Dec 15 '14 at 17:53
  • @DanNissenbaum a "class [template member]" is also a "partial specialization ... or primary class or function template", so is covered by those. I meant it to be a "[class template] member". These are not templates, therefore my phrasing "template or class template member". – Johannes Schaub - litb Dec 15 '14 at 22:28
  • The mentioning of it in the first bullet should have said "class member", not "class template member" (which is what the Standard uses when defining "specialization"). – Johannes Schaub - litb Dec 15 '14 at 22:38
13

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.

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • Note that my example for specialization isn't really a great one because it's a function so you can just overload it. However if you need to do this inside a class template, it would be done that way, e.g. you have some traits class for types and one of them is converting to a string. It's just easier for demonstration purposes to show why you specialize for a type through that function. – CashCow Aug 30 '12 at 10:09
10

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
Francis
  • 737
  • 1
  • 7
  • 21
0

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