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?
source to share
To keep things short when talking about class templates:
- Explicit (full) specialization: all template arguments are specified
- Partial specialization: customize a template by specifying only a subset of template arguments
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
To respond to your update:
- Template specialization cannot add arguments, it can only specialize on existing arguments
source to share
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;
};
source to share
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;
source to share