Для занятий да. Для функций нет и да.
Частичная специализация шаблонов хороша для классов, но для глобальных функций это немного сложнее.
Для классов вы просто опускаете специализированные аргументы из списка параметров шаблона и включаете его в определение класса:
// 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] );
}
};
Для глобальных функций вы не можете этого сделать. Вы можете определить функцию, которая является полностью общей, или полностью специализированной - частичная специализация функций запрещена.
Однако вы можете частично специализировать функцию, создав ее в качестве прокси для статической функции частично специализированного класса.
1012 *, например *
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
}
};
Затем вы можете специализировать foo_impl
по своему усмотрению, что будет отражено в foo
.