作为大多数C++程序员应该知道的,自由函数的部分模板特化是不允许的。例如,以下代码是非法的C++代码:
template <class T, int N>
T mul(const T& x) { return x * N; }
template <class T>
T mul<T, 0>(const T& x) { return T(0); }
// error: function template partial specialization ‘mul<T, 0>’ is not allowed
然而,类/结构体的部分模板特化是被允许的,并且可以被利用来模仿自由函数的部分模板特化功能。例如,可以通过使用以下方式实现上一个示例中的目标:
template <class T, int N>
struct mul_impl
{
static T fun(const T& x) { return x * N; }
};
template <class T>
struct mul_impl<T, 0>
{
static T fun(const T& x) { return T(0); }
};
template <class T, int N>
T mul(const T& x)
{
return mul_impl<T, N>::fun(x);
}
虽然更加臃肿,不够简洁,但它完成了工作——对于使用mul
的用户而言,他们得到了期望的部分特化。
我的问题是:在编写模板化自由函数(旨在供他人使用)时,您是否应自动将实现委托给类的静态方法函数,以便您库的用户可以随意实现部分特化,还是按照常规方式编写模板化函数,并接受人们无法进行特化的事实?
fun<U, N>(u)
,所以你不能重载(N
在参数中没有出现)。但是我认为如果“重载”是可能的,那就是首选的方式。很好的例子是std::swap
或者std::begin
或者std::end
(后两个是 C++0x 的函数)。请注意,Sutter 的文章是9年前写的。不确定他是否仍然推荐使用“委托给类”的方式。而且我认为它不太适用:无法与 ADL 兼容 - 你将不得不处理各种命名空间并特化它们的模板。没有很好的解决方法。 - Johannes Schaub - litb