Rajeshwar
Rajeshwar

Reputation: 11681

Understanding Template Partial Specialization

I am trying to understand the concept of partial specialization of templates. However I seem to be confusing it with template 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 the following

test<int*> s;

and this calls the specialized template. How can i call the partially specialized class. Could anyone please also explain the difference between partial and specialized template with an example ?

Update:

After going through the answers I realized that partial template specialization assists only when a subset of the parameters need 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 that ?

Upvotes: 3

Views: 694

Answers (4)

erenon
erenon

Reputation: 19148

This is a template:

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

And you can specialize it:

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

You might also leave one of the parameters free (partial specialization):

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

Upvotes: 1

TheGoatMan7
TheGoatMan7

Reputation: 610

Take a look at this link regarding template specialization.

template <>

Will be the way you handle a specific type, while

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

Is how you handle generic types. Of couse

test<int*> s;

calls the specialized template, because that is what you specified above. To call the partially specialized, call with any other type for the template. For example

test<char*> s;

Upvotes: 0

There are two effects which can be achieved with partial specialisation.

One, you can "fix" one or more template parameters to concrete values, while keeping the others "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 definition for the template for a more specific version of a (still generic) template parameter:

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 precisely what your original code is doing.

You can of course also combine the two, like this:

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

Upvotes: 2

quantdev
quantdev

Reputation: 23813

To make things short, when talking about class templates :

Example of all 3 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 answer your update :

  • A template specialization cant add arguments, it can only specialize existing arguments

Upvotes: 5

Related Questions