Someone explain why there is ambiguity here, please?

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?

+5
source share
1 answer

I don’t know why gcc rejects your code, but if you have C ++ 14 support, a less tedious solution is to use std::make_index_sequence to create a package with Size elements, then output the package and deploy it again like this:

 template <typename T, template <T...> class Pack, T Value, size_t... indices> auto FillHelper(std::index_sequence<indices...>) -> Pack<(indices, Value)...>; template <typename T, template <T...> class P, int Size, T Value> using Fill = decltype(FillHelper<T, P, Value>(std::make_index_sequence<Size>())); 

Link: http://coliru.stacked-crooked.com/a/7771560a1f32461d

+1
source

All Articles