【发布时间】:2017-07-28 16:09:37
【问题描述】:
我正在 C++ 中实现二项式系数(n 选择 k)函数。 除了使用“正常”函数(在运行时评估)之外,这还可以使用模板元编程来完成(当参数在编译时已知时):
template <unsigned int n, unsigned int k>
struct Binomialkoeffizient {
static const unsigned int value = Binomialkoeffizient<n, k-1>::value * (n-k+1) / k;
};
template <unsigned int n>
struct Binomialkoeffizient<n, 0> {
static const unsigned int value = 1;
};
这个实现的缺点是,在 k > n/2 的情况下,它没有利用定理 n 选择 k = n 选择 n-k。因此可能会发生不必要的算术溢出,例如49选43会溢出,而49选6不会。
我尝试了以下方法来改善这一点:
template <unsigned int n, unsigned int k>
struct Binomialkoeffizient {
static const unsigned int value = (2*k > n) ? Binomialkoeffizient<n, n-k>::value : Binomialkoeffizient<n, k-1>::value * (n-k+1) / k;
};
template <unsigned int n>
struct Binomialkoeffizient<n, 0> {
static const unsigned int value = 1;
};
不幸的是,我收到了fatal error: template instantiation depth exceeds maximum of 900。
这似乎是由于在递归模板实例化过程中没有评估三元运算符。
使用?: 有哪些可能的替代方法?
我对 C++11 之前的解决方案和更新的解决方案都感兴趣(也许std::enable_if 有帮助,但我不太了解)。
【问题讨论】:
-
您是否尝试过使用
std::conditional? -
您能详细说明一下吗?我不确定如何准确使用它。它似乎也只适用于 C++11 以上。
-
@Fabian 是的,它是 C++11。第 1 步:在 C++11 中使用
std::conditional解决它。第 2 步:用 C++03 编写my::conditional。第 3 步:利润。 -
@Yakk 现在我终于知道什么了????是。
标签: c++ templates template-meta-programming c++03