我正在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