How can an element of a type list using L = type_list<T1, T2, ...>
be retrieved by index, like std::tuple_element, preferrably in a non recursive way?
I want to avoid using tuples as type lists for use cases, that require instantiation for passing a list like f(L{})
.
template<typename...> struct type_list {};
using L = typelist<int, char, float, double>;
using T = typeAt<2, L>; // possible use case
Not sure if an iteration using std::index_sequence and a test via std::is_same of the std::integral_constant
version of the index is a good aproach.
CodePudding user response:
I want to avoid using tuples as type lists for use cases, that require instantiation for passing a list like
f(L{})
If you don't want to instanciate std::tuple
but you're ok with it in
unevaluated contexts, you may take advantage of std::tuple_element
to
implement your typeAt
trait:
template <std::size_t I, typename T>
struct typeAt;
template <std::size_t I, typename... Args>
struct typeAt<I, type_list<Args...>> : std::tuple_element<I, std::tuple<Args...>> {};
// ^ let library authors do the work for you
using L = type_list<int, char, float, double>;
using T = typename typeAt<2, L>::type;
static_assert(std::is_same<T, float>::value, "");
CodePudding user response:
You might re-implement a simplified non-recursive tuple-like version if you don't want to use std::tuple
:
template <std::size_t I, typename T>
struct type_list_leaf
{
using type = T;
};
template <typename T> struct tag{ using type = T; };
template <typename Seq, typename...>
struct type_list_impl;
template <std::size_t... Is, typename... Ts>
struct type_list_impl<std::index_sequence<Is...>, Ts...> : type_list_leaf<Is, Ts>...
{
};
template <std::size_t I, typename T>
tag<T> type_list_element_tag(const type_list_leaf<I, T>&);
template <std::size_t I, typename Tuple>
using tuple_element = decltype(type_list_element_tag<I>(std::declval<Tuple>()));
template <std::size_t I, typename Tuple>
using tuple_element_t = typename tuple_element<I, Tuple>::type;
template <typename ... Ts>
using type_list = type_list_impl<std::make_index_sequence<sizeof...(Ts)>, Ts...>;