テンプレートでたらいまわし(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