Does the stdlib provide a type list?

Viewed 322

In modern C++, does the standard library provide a type list template?

int main() {
    using int_types = type_list<int,long,short,char>;
    std::cout << length<int_types>::value << ' '
              << typeid(element<2,int_types>::type).name();
}

Note that int_types does not store any values (as std::tuple does). It's merely a list of types.

3 Answers

It seems to me that, in modern C++ standard library, nearest what you want is std::tuple.

If the problem is that std::tuple store values of the listed types (so, I suppose, can be a problem instantiate an object of that type) it's easy write a instantiable object that wraps a std::tuple using without instantiate the std::tuple itself.

I mean... given a wrapper like this

template <typename ... Ts>
struct wrapTuple
 {
   using type = std::tuple<Ts...>;

   template <std::size_t N>
   using element = std::tuple_element_t<N, type>;

   static constexpr auto length { std::tuple_size_v<type> };
 };

you can write the following lines without instantiate the wrapper

   using int_types = wrapTuple<int, long, short, char>;

   std::cout << int_types::length << ' '
      << typeid(int_types::element<2u>).name() << std::endl;

but you can also instantiate it without instantiate the std::tuple

   int_types it;

   std::cout << it.length << ' '
      << typeid(decltype(it)::element<2u>).name() << std::endl;

Use std::tuple type but don't instantiate it:

#include <iostream>
#include <tuple>

int main()
{
    using int_types = std::tuple<int, long, short, char>;
    std::cout << std::tuple_size_v<int_types> << ' '
        << typeid(std::tuple_element_t<2, int_types>).name();
}

MSVC output:

4 short

GCC output:

4 s

Clang output:

4 s

In the end, I did something like this:

template<typename ...T> struct type_list {};

template<typename    L> struct length;
template<typename ...T> struct length<type_list<T...>> {static const std::size_t value=sizeof...(T);};

template<std::size_t I, typename L>
struct element;
template<typename F, typename ...T> 
struct element<0, type_list<F, T...>> {using type=F;};
template<std::size_t I> 
struct element<I, type_list<>>        {using type=void;};
template<std::size_t I, typename F, typename ...T> 
struct element<I, type_list<F, T...>> {using type=typename element<I-1,type_list<T...>>::type;};

int main() {
    using int_types = type_list<int,long,short,char>;
    std::cout << length<int_types>::value << '\n'
              << typeid(element<2,int_types>::type).name() << '\n';
    return 0;
}
Related