我正在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;
};
这种实现的缺陷在于,它不使用定理n在k> n/2的情况下选择k = n选择nk。因此可能发生不必要的算术溢出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
。
这似乎是由递归模板实例化过程中未评估三元运算符的事实引起的。
什么是使用?:
的可能替代方案?
我对pre-C++ 11解决方案和更新的解决方案很感兴趣(也许std::enable_if
有帮助,但我对此不太了解)。
您是否尝试过使用['std :: conditional'](http://en.cppreference.com/w/cpp/types/conditional)? – NathanOliver
请您详细说明一下吗?我不确定如何正确使用它。它似乎也只适用于C++ 11以上。 – Fabian
@Fabian是的,它是C++ 11。第1步:使用'std :: conditional'在C++ 11中解决它。第2步:在C++ 03中编写'my :: conditional'。第3步:利润。 – Yakk