Understanding Partial Template Specialization

I am trying to understand the concept of partial template specialization. However, I seem to be confusing it with specialized specialization. I am considering the following two examples:

template <typename T> 
struct test
{
   ///Some stuff
};

template <> //Specialization
struct test<int*>
{
   ///Some stuff
};


template<typename t> //Partial specialization
struct test<t*>
{
   ///Some stuff
};

      

I am trying to do the following

test<int*> s;

      

and that calls a custom template. What can I call a partially specialized class. Can anyone explain also the difference between partial and specialized pattern with example?

Update:

After going through the answers, I realized that partial specialization only helps if a subset of the parameters needs to be specialized. So I tried something like this

template <>
struct test<int*>
{
};


//Partial Specialized
template<typename t>
struct test<t, std::string>
{
};

test<int*,std::string> s;  //Error : Too many arguments for class template

      

Why is this?

+3


source to share


4 answers


To keep things short when talking about class templates:

An example of all three cases:

#include <iostream>

template<typename T, typename U> //Primary template
struct test
{
   void foo() { std::cout << "\nPrimary"; }
};

template <typename T> //Specialization
struct test<T, int*>
{
   void foo() { std::cout << "\nPartial Specialization"; }
};


template<> //Full specialization
struct test<int*, int*>
{
   void foo() { std::cout << "\nFull Specialization"; }
};

int main()
{
    test<int, double> t1;
    t1.foo();

    test<double, int*> t2;
    t2.foo();

    test<int*, int*> t3;
    t3.foo();
}

      

Output:



Primary

Partial specialization

Full specialization

Live demo


To respond to your update:

  • Template specialization cannot add arguments, it can only specialize on existing arguments
+5


source


This is the template:

tempalte <typename A, typename B>
class Foo {};

      

And you can highlight it:



template <>
class Foo<int, int> {};

      

You can also leave one of the options free (partial specialization):

template <typename B>
class Foo<std::string, B> {};

      

+1


source


There are two effects that can be achieved with partial specialization.

First, you can "fix" one or more of the template parameters for specific values, leaving the rest "unbound". Here's an example:

template <class A, class B>
struct Foo  // The primary template
{
  static const int i = 0;
};

template <class A>
struct Foo<A, int>  // Partial specialisation which "fixes" B
{
  static const int i = 1;
};

template <>
struct Foo<char, int>  // Full specialisation
{
  static const int i = 2;
};

int main()
{
  std::cout << Foo<char, double>::i;  // 0
  std::cout << Foo<double, int>::i << Foo<void, int>::i;  // 11
  std::cout << Foo<char, int>::i;  //2
}

      

Two, you can provide an alternative template definition for a more specific version of the template parameter (still generic):

template <class A>
struct Bar  // Primary template
{
  static const int i = 0;
};

template <class A>
struct Bar<A*>  // Patrial specialisation for pointers
{
  static const int i = 1;
};

template <>
struct Bar<int*>  // Full specialisation
{
  static const int i = 2;
};

int main()
{
  std::cout << Bar<int>::i;  // 0
  std::cout << Bar<void*>::i << Bar<int**>::i;  // 11
  std::cout << Bar<int*>::i;  // 2
}

      

This is exactly what your original code does.

You can of course also combine the two, for example:

template <class A>
struct Foo<std::vector<A>, int>  // Partial specialisation of primary Foo from above, for any std::vector and an int
{
  static const int i = 3;
};

      

+1


source


Take a look at the link regarding the specialization.

template <>

      

Will you handle a specific type while

template<typename t> //Partial specialization
struct test<t*>

      

How do you handle generic types. Of couse

test<int*> s;

      

calls a specialized template because that's what you listed above. To invoke a partially specialized call with any other type for a template. for example

test<char*> s;

      

0


source







All Articles