Fill<T, Pack, Size, Value> must be of type Pack<Value, Value, ..., Value> , where the value is repeated. Size times. Can someone explain why this is ambiguous?
template <typename T, template <T...> class Pack, int Size, int Count, typename Output, T Value> struct FillHelper; template <typename T, template <T...> class P, int Size, int Count, T... Output, T Value> struct FillHelper<T, P, Size, Count, P<Output...>, Value> : FillHelper<T, P, Size, Count + 1, P<Output..., Value>, Value> {}; template <typename T, template <T...> class P, int Size, T... Output, T Value> struct FillHelper<T, P, Size, Size, P<Output...>, Value> { using type = P<Output...>; }; template <typename T, template <T...> class P, int Size, T Value> using Fill = typename FillHelper<T, P, Size, 0, P<>, Value>::type; template <int...> struct Pack; int main() { using T = Fill<int, Pack, 10, 4>; }
while this is not so:
template <typename T, int Size, int Count, typename Output, T Value> struct FillHelper; template <typename T, template <T...> class P, int Size, int Count, T... Output, T Value> struct FillHelper<T, Size, Count, P<Output...>, Value> : FillHelper<T, Size, Count + 1, P<Output..., Value>, Value> {}; template <typename T, template <T...> class P, int Size, T... Output, T Value> struct FillHelper<T, Size, Size, P<Output...>, Value> { using type = P<Output...>; }; template <typename T, template <T...> class P, int Size, T Value> using Fill = typename FillHelper<T, Size, 0, P<>, Value>::type; template <int...> struct Pack; int main() { using T = Fill<int, Pack, 10, 4>; }
It turns out I indirectly noticed that the second is shorter and therefore better than the first, but I was puzzled by why the first would not compile. I get an error with GCC 4.9.2, which is very recent. Error with Visual Studio 2013 too. By the way, a better solution than the second code is welcome.
Update:. Reducing the problem, it turns out that having a template in specializations is NOT a problem, because it compiles with GCC 4.9.2 (and Visual Studio 2013 too):
template <typename T, template <T...> class Pack, int Size, int Count> struct F; template <typename T, template <T...> class P, int Size, int Count> struct F : F<T, P, Size, Count + 1> {}; template <typename T, template <T...> class P, int Size> struct F<T, P, Size, Size> { using type = int; }; template <int...> struct Pack; int main() { using T = F<int, Pack, 10, 0>::type; }
So what is the problem in the first code causing confusion with GCC and VS?