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();
}