Recursive template class and specialized base case are causing MSVC error C1001 (works fine on GCC and Clang)

  c++, c++17, template-meta-programming

I would like to know why the following is rejected by MSVC and not Clang or GCC.
I adapted the code from a post I read about a while ago and was playing around with it.
There is no wider context, this is everything.
I had time to kill and my laptop, this was the result.

Basically it generates a compile time list of integers to aggregate initialize type T.

        // Base case
        template <int...LIST>
        struct List<LAST_ARG , LIST...> // **** changing LAST_ARG to 8 fixes the problem ****
        {   
            using Type_t = List<LIST...>;
        };

        // Recursive case
        template <int PUSH_BACK, int...LIST>
        struct List<PUSH_BACK, LIST...>
        {   
            // **** CAUSES ERROR C1001! (Clang and GCC have no issues) ****
            using Type_t = typename List<PUSH_BACK+1, LIST..., PUSH_BACK+1>::Type_t;
        };

Here’s the full code.

    #include <cstddef>
    #include <iostream>
    
    // THIS IS JUST A TEST CLASS
    struct Vector
    {
        float a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0;
        
        float operator[](std::size_t index) const { return *(&a + index); }
        
        void display() const
        {   std::cout << "[ ";
            for(std::size_t i = 0; i < 9; ++i)
                std::cout << this->operator[](i) << " ";
            std::cout << "]";
        }
    };
    
    template <typename T, int FIRST_ARG, int LAST_ARG>
    struct MakeList
    {
        static_assert(FIRST_ARG < LAST_ARG);
    
        static constexpr T init() noexcept
        {   return do_init(typename List<FIRST_ARG-1>::Type_t());
        }
    
    protected:
        // Base template
        template <int...LIST>
        struct List
        {};

        // Base case
        template <int...LIST>
        struct List<LAST_ARG , LIST...> // **** changing LAST_ARG to 8 fixes the problem ****
        {   
            using Type_t = List<LIST...>;
        };
    
        // Recursive case
        template <int PUSH_BACK, int...LIST>
        struct List<PUSH_BACK, LIST...>
        {   
            // **** CAUSES ERROR C1001! (Clang and GCC have no issues) ****
            using Type_t = typename List<PUSH_BACK+1, LIST..., PUSH_BACK+1>::Type_t;
        };
    
        template <int...INDEXES>
        static constexpr T do_init(List<INDEXES...>) noexcept
        {   return{ INDEXES... };
        }
    };
    
    int main()
    {
        const Vector v = MakeList<Vector, 0, 8>::init();
        
        v.display();
    }

Source: Windows Questions C++

LEAVE A COMMENT