Итак, у меня есть список типов шаблонов вроде этого:
template <typename... Types>
struct type_list
{
};
Я создал такую функцию доступа:
template<class TypeList, size_t ElementIndex>
struct at;
template <template<typename...> class TypeList, typename Head, typename... OtherTypes, size_t ElementIndex>
struct at< TypeList<Head, OtherTypes...>, ElementIndex>
{
static_assert(ElementIndex < (size_v< TypeList<Head, OtherTypes...> >), "at_t : ElementIndex is bigger than list size");
using type = if_else_t < ElementIndex == 0, Head, typename at< TypeList<OtherTypes...>, ElementIndex - 1 >::type >;
};
template <template<typename...> class TypeList, typename Last, size_t ElementIndex>
struct at< TypeList<Last>, ElementIndex>
{
static_assert(ElementIndex < (size_v< TypeList<Last> >), "at_t : ElementIndex is bigger than list size");
using type = Last;
};
template<class TypeList, size_t ElementIndex>
using at_t = typename at<TypeList, ElementIndex>::type;
if_else_t<>
имеет следующую реализацию:
template<bool Condition, typename True, typename False>
struct if_else
{
using type = True;
};
template<typename True, typename False>
struct if_else<false, True, False>
{
using type = False;
};
Теперь, если я тестирую функцию с помощью:
static_assert(std::is_same_v< bool, at_t< type_list<int, float, bool, char>, 2 > >, "at_t : Bad result");
, я запускаю static_assert, который проверяет, больше ли ElementIndex, чем размер списка. Из вывода компилятора я ясно вижу, что at<>
никогда не останавливает рекурсию, пока ElementIndex не достигнет своего числового предела (случай, когда ElementIndex = 0 - 1) и сработает static_assert.
Что я делаю неправильно?
Идеальный ответ также должен включать лучшую, более элегантную реализацию at<>
:)
Обратите внимание, что я использую MSV C и C ++ 17.