模板类体内的模板元编程

时间:2013-05-12 17:36:06

标签: c++ templates c++11 metaprogramming

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

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。

干杯

1 个答案:

答案 0 :(得分: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(...){}

这具有相同的效果,但采用更多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时调用,并且将由重载决策选择,因为它比第一次重载更受约束。