我正在尝试在模板类/结构体内编写一个部分专用的模板函数。部分特化是为了执行递归模板元编程。
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。
干杯
答案 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
时调用,并且将由重载决策选择,因为它比第一次重载更受约束。