您可以通过重载函数(而不是专门化它)然后使用enable_if 选择性地仅启用一个或其他重载来实现所需的结果:
template<size_t D> typename std::enable_if<D!=0, double>::type my_func(...){}
template<size_t D> typename std::enable_if<D==0, double>::type my_func(...){}
enable_if 约束意味着当D!=0 只有第一个重载是可行的函数时,D==0 只有第二个重载是可行的函数。
在 C++03 中,您可以使用 boost::enable_if_c 做同样的事情。
我首选的解决方案是用自定义特征类型替换丑陋的 enable_if 用法,可能是这样的:
template<size_t> struct if_zero { typedef double disable; };
template<> struct if_zero<0> { typedef double enable; };
template<size_t D> typename if_zero<D>::disable my_func(...){}
template<size_t D> typename if_zero<D>::enable my_func(...){}
这具有相同的效果,但更像literate programming 风格。
另一种更容易阅读的形式是:
template<bool, typename T> struct If_ { typedef T enable; };
template<typename T> struct If_<false, T> { };
template<bool B, typename T> using If = typename If_<B, T>::enable;
template<size_t D> If<D!=0, double> my_func(...){}
template<size_t D> If<D==0, double> my_func(...){}
我认为"Concepts Lite" 提案将通过像这样约束第二个重载以更简洁的方式实现这一点:
template<size_t D> double my_func(...){}
template<size_t D> requires (D == 0)
double my_func(...){}
这里的第二个重载只能在D==0 时调用,并且将由重载决议选择,因为它比第一个重载更受约束。