3

我正在尝试在模板类/结构的主体中编写一个部分专用的模板函数。部分特化用于执行递归模板元编程。

template<size_t N>
struct my_class {

template<size_t D> double my_func(...){}

template<> double my_func<0>(...){}

double other_func(...){ return my_func<N-1>(...); }
};

但是 g++(使用-std=c++0x选项)抱怨说不能在类/结构中部分专门化模板函数,并迫使我在单独的命名空间中编写类范围之外的模板函数my_func,就好像它们是静态的,最终传递了所有私有类变量并使代码非常混乱(所有成员变量都可以很容易地被this引用)。

有没有办法可以进行部分模板专业化(我也可以将函数作为my_class的私有子类的静态成员)和同一个类中的元编程?

这使代码更简洁,更易于维护。我正在使用 Ubuntu 12.04 和 gcc 4.6。

干杯

4

1 回答 1

4

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(...){}

这具有相同的效果,但采用了更加有文化的编程风格。

另一种更容易阅读的形式是:

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并且将由重载决议选择,因为它比第一个重载更受约束。

于 2013-05-12T17:41:56.073 回答