メタプログラミングで素数計算

良いもの。悪いもの。: C++のテンプレートで素数を求めるを参考にさせてもらった。これとちがって、Primeとするとn番目の素数を求める。


テンプレートの引数を説明すると、nはいいとして、pは今調べている素数候補、iはpが割り切れるかどうか調べているi番目の素数、rは剰余、bは素数と判定されたかどうか。
250番目までは求まる。それより大きいと、VC2005では「 fatal error C1202: 再帰的な型の指定または関数の依存関係が複雑すぎます。」というメッセージが出る。Primeが入れ子になってなければいいのかも。


#include

template
struct Prime {
enum { value = Prime<n, p, i + 1, p % Prime<i>::value,
(Prime<i>::value * Prime<i>::value > p)>::value };
};

template<int n, int p, int i, bool b>
struct Prime<n, p, i, 0, b> {
enum { value = Prime<n, p + 2, 1, 1, false>::value };
};

template<int n, int p, int i, int r>
struct Prime<n, p, i, r, true> {
enum { value = p };
};

template<int n>
struct Prime<n, 0, 1, 1, false> {
enum { value = Prime<n, Prime<n-1>::value + (n == 2 ? 1 : 2),
1, 1, false>::value };
};

template<>
struct Prime<1, 0, 1, 1, false> {
enum { value = 2 };
};

int main() {
std::cout << Prime<100>::value << std::endl; // 541
}