阶乘
#include <cstdint>
template<uint64_t N>
struct Fact
{
enum { Value = N * Fact<N - 1>::Value };
};
template<>
struct Fact<1ULL>
{
enum { Value = 1ULL };
};
斐波那契额数列
template<uint64_t N>
struct Fib
{
enum { Value = Fib<N - 1>::Value + Fib<N - 2>::Value };
};
template<>
struct Fib<2ULL>
{
enum { Value = 1ULL };
};
template<>
struct Fib<1ULL>
{
enum { Value = 1ULL };
};
乘方运算
template<int64_t base, uint64_t exp>
struct Pow
{
enum { Value = base * Pow<base, exp-1>::Value };
};
template<int64_t base>
struct Pow<base, 1>
{
enum { Value = base };
};
template<int64_t base>
struct Pow<base, 0>
{
enum { Value = 1 };
};
测试
#include <iostream>
using ::std::cout;
using ::std::endl;
int main(int argc, char const *argv[])
{
cout << Fact<5ULL>::Value << endl;
cout << Fib<10ULL>::Value << endl;
cout << Pow<2, 10>::Value << endl;
return 0;
}
运行结果如下
120
403200
1024
新的写法
上述代码是C++11
以前的写法,借助了enum
在编译期求值的特性。C++11
以后可使用static constexpr
变量取代。具体做法如下:
#include <cstdint>
template<uint64_t N>
struct Fact
{
static constexpr uint64_t Value = N * Fact<N - 1>::Value;
};
template<>
struct Fact<1ULL>
{
static constexpr uint64_t Value = 1ULL;
};
template<uint64_t N>
struct Fib
{
static constexpr uint64_t Value = Fib<N - 1>::Value + Fib<N - 2>::Value;
};
template<>
struct Fib<2ULL>
{
static constexpr uint64_t Value = 1ULL;
};
template<>
struct Fib<1ULL>
{
static constexpr uint64_t Value = 1ULL;
};
template<int64_t base, uint64_t exp>
struct Pow
{
static constexpr int64_t Value = base * Pow<base, exp-1>::Value;
};
template<int64_t base>
struct Pow<base, 1>
{
static constexpr int64_t Value = base;
};
template<int64_t base>
struct Pow<base, 0>
{
static constexpr int64_t Value = 1;
};
修改完后用法和之前完全一样。
借助C++17
可以进一步简化,如下:
#include <cstdint>
template <uint64_t N>
struct Fact
{
static constexpr uint64_t Value = []
{
if constexpr (N == 1)
{
return 1;
}
else
{
return N * Fact<N - 1>::Value;
}
}();
};
template <uint64_t N>
struct Fib
{
static constexpr uint64_t Value = []
{
if constexpr (N < 3)
{
return 1;
}
else
{
return Fib<N - 1>::Value + Fib<N - 2>::Value;
}
}();
};
template<int64_t base, uint64_t exp>
struct Pow
{
static constexpr int64_t Value = [] -> int64_t
{
if constexpr (exp == 1)
{
return base;
}
else if (exp == 0)
{
return 1;
}
else
{
return base * Pow<base, exp-1>::Value;
}
}();
};