私はC++で二項係数(n choose 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を選ぶ.k> n/2の場合は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
を取得します。
これは、再帰的テンプレートインスタンス化のプロセス中に3項演算子が評価されないことが原因であると考えられます。
?:
を使用すると可能な代替方法は何ですか?
私は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