テンプレートでたらいまわし(5回目)
Typelistを使わない方法。この方がさらに速い(しかも引数が0の場合も動く)。
#include <iostream> /* True */ class True; /* False */ class False; /* Bool */ template <bool b> struct Bool; template <> struct Bool<true> { typedef True Result; }; template <> struct Bool<false> { typedef False Result; }; /* Tarai */ template <int x, int y, int z> struct Tarai; template <class B, int x, int y, int z> struct Tarai1; template <int x, int y, int z> struct Tarai { typedef typename Bool< x <= y >::Result B; enum { value = Tarai1<B, x, y, z>::value }; }; template <int x, int y, int z> struct Tarai1<True, x, y, z> { enum { value = y }; }; template <int x, int y, int z> struct Tarai1<False, x, y, z> { enum { xx = Tarai<x - 1, y, z>::value }; enum { yy = Tarai<y - 1, z, x>::value }; enum { zz = Tarai<z - 1, x, y>::value }; enum { value = Tarai<xx, yy, zz>::value }; }; int main(int argc, char *argv[]) { int n = Tarai<48, 24, 0>::value; std::cout << n << std::endl; return 0; }
% time g++ tarai5.cpp real 0m37.622s user 0m36.378s sys 0m0.368s %time ./a.out 48 real 0m0.002s user 0m0.000s sys 0m0.004s
または、
#include <iostream> /* Tarai */ template <int x, int y, int z> struct Tarai; template <bool b, int x, int y, int z> struct Tarai1; template <int x, int y, int z> struct Tarai { enum { value = Tarai1<(x <= y), x, y, z>::value }; }; template <int x, int y, int z> struct Tarai1<true, x, y, z> { enum { value = y }; }; template <int x, int y, int z> struct Tarai1<false, x, y, z> { enum { xx = Tarai<x - 1, y, z>::value }; enum { yy = Tarai<y - 1, z, x>::value }; enum { zz = Tarai<z - 1, x, y>::value }; enum { value = Tarai<xx, yy, zz>::value }; }; int main(int argc, char *argv[]) { int n = Tarai<48, 24, 0>::value; std::cout << n << std::endl; return 0; }
% time g++ tarai5-2.cpp real 0m35.941s user 0m34.978s sys 0m0.348s % time ./a.out 48 real 0m0.002s user 0m0.000s sys 0m0.004s