For classes, yes. For functions, no and yes.
Partial template specialization is fine for classes, but for global functions it's a little more tricky.
For classes, you simply omit the specialized arguments from the template parameter list and include it in the class definition:
// General template class for a vector
template <class T, int N>
struct Vector
{
T e[N];
};
// Specialization for N=3
template <class T> // omit the N
struct Vector<T, 3> // and include it here
{
T e[3];
static Vector<T, 3> cross(const Vector<T, 3>& a, const Vector<T, 3>& b)
{
return Vector<T, 3>( a.e[1] * b.e[2] - a.e[2] * b.e[1],
a.e[2] * b.e[0] - a.e[0] * b.e[2],
a.e[0] * b.e[1] - a.e[1] * b.e[0] );
}
};
For global functions, you can't do that. You can either define a function that is fully general, or fully specialized -- partial specialization of functions is disallowed.
However, you can partially specialize a function by creating it as a proxy for a static function of a partially specialized class.
e.g.
template <class A, class B>
void foo(A a, B b)
{
foo_impl::fun(a, b);
}
template <class A, class B>
struct foo_impl
{
static void fun(A a, B b)
{
// real implementation here
}
};
You can then specialize foo_impl
in any way you want, and that will be reflected in foo
.