I don't understand why the following:
template <typename...U>
struct always_false : std::false_type {};
template <size_t I, typename FRONT, typename...Ts>
struct split_impl
{
static_assert(always_false<Ts...>::value, "Not enough types to index");
};
template <typename...Ts, typename...Us>
struct split_impl<0, std::tuple<Ts...>, Us...>
{
using front = std::tuple<Ts...>;
using rest = std::tuple<Us...>;
};
template <size_t I, typename...Ts, typename T, typename...Us>
struct split_impl<I, std::tuple<Ts...>, T, Us...>
: split_impl<I - 1, std::tuple<Ts..., T>, Us...>
{};
template <size_t I, typename...Ts>
struct split : split_impl<I, std::tuple<>, Ts...> {};
template<int> struct x {};
split<0, x<0>, x<1>>::rest z = nullptr;
results in an ambiguous partial specialization:
source_file.cpp:15:8: note: partial specialization matches [with Ts = <>, Us = <x<0>, x<1>>]
struct split_impl<0, std::tuple<Ts...>, Us...>
^
source_file.cpp:22:8: note: partial specialization matches [with I = 0, Ts = <>, T = x<0>, Us = <x<1>>]
struct split_impl<I, std::tuple<Ts...>, T, Us...>
^
From my POV, when the first parameter is 0
, it must accept the first as being a match.
Please note that I'm not looking for a way to get around this, I'm asking why this is not working. What partial specialization rules are forbidding this? This happens in clang, g++ and I assume vc++ is not matching for the same reason, even though the error is not helpful.