vendredi 22 juillet 2016

Compiler dependent error when computing compile-time array

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?

Aucun commentaire:

Enregistrer un commentaire