Reputation: 11681
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
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
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
Reputation: 171177
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
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
To answer your update :
Upvotes: 5