My goal is to compute array of factorials at compile time without creating any class objects or calling static functions. Here is minimal code:
#include <iostream>
#include <cinttypes>
#include <array>
namespace CompileTime
{
enum {MaxFactorial = 10};
template<size_t N, size_t I = N-1>
class Factorial : public Factorial<N, I-1>
{
public:
static const uint64_t value;
};
template<size_t N>
class Factorial<N,1> : public Factorial<N, 0>
{
public:
static const uint64_t value;
};
template<size_t N>
class Factorial<N,0>
{
public:
static const uint64_t value;
static std::array<uint64_t,N> array;
};
template<size_t N>
const size_t Factorial<N,1>::value = Factorial<N,0>::array[1] = 1;
template<size_t N>
const size_t Factorial<N,0>::value = Factorial<N,0>::array[0] = 1;
template <size_t N, size_t I>
const size_t Factorial<N,I>::value = Factorial<N,0>::array[I] =
I * Factorial<N, I-1>::value;
template <size_t N>
std::array<uint64_t,N> Factorial<N, 0>::array;
template class Factorial<MaxFactorial>;
typedef Factorial<MaxFactorial> PrecomputerFactorial;
}
int main()
{
using CompileTime::PrecomputerFactorial;
for(auto x : PrecomputerFactorial::array)
std::cout << x << std::endl;
std::cout << std::endl;
}
Compiling with GCC 5.3.0 gives program output:
0
1
2
6
24
120
720
5040
40320
362880
And with MSVC 2015:
0
1
0
0
0
0
0
0
0
0
I have two questions:
First, why array[0]
has value 0
in both cases, despite being set to 1
here:
template<size_t N>
const size_t Factorial<N,0>::value = Factorial<N,0>::array[0] = 1;
Second, why MSVC 2015 fails to compute it?