Вероятно, это зависит от точной (под) версии VS2017, так как моя не производит ICE для кода. Тем не менее, код все еще проблематичен, так как он может создавать экземпляр std::tuple_element<2147483647, T>
или что-то подобное. Вы должны убедиться, что только правильная ветвь когда-либо оценивается. Замените ваше определение get_type
следующим:
template <int I, typename T, bool negative = (I < 0)>
struct get_type_impl;
template <int I, typename T>
struct get_type_impl<I, T, true>
{
using type = typename std::tuple_element<static_cast<int>(std::tuple_size<T>::value) + I, T>::type;
};
template <int I, typename T>
struct get_type_impl<I, T, false>
{
using type = typename std::tuple_element<I, T>::type;
};
template <int I, typename T>
using get_type = typename get_type_impl<I, T>::type;
Это работает для меня на моем VS 2017 (кл версия 19.12)