简体   繁体   中英

Typelist of nested types

I've got a typelist providing the following interface :

 template <typename... Ts>
    struct type_list
    {
        static constexpr size_t length = sizeof...(Ts);

        template <typename T>
        using push_front = type_list<T, Ts...>;


        template <typename T>
        using push_back = type_list<Ts..., T>;
        
        // hidden implementation of complex "methods"

        template <uint64_t index>
        using at;

        struct pop_front;

        template <typename U>
        using concat;

        template <uint64_t index>
        struct split;

        template <uint64_t index, typename T>
        using insert;

        template <uint64_t index>
        using remove;
    };

In another piece of code, I have such a typelist TL of types statically inheriting a base class providing such an interface :

template<typename Derived>
struct Expression {
   using type1 = typename Derived::_type1;
   using type2 = typename Derived::_type2;
};

struct Exp1 : Expression<Exp1> {
    template<typename> friend struct Expression;
    private:
    using _type1 = float;
    using _type2 = int;
};

struct Exp2 : Expression<Exp2> {
    template<typename> friend struct Expression;
    private:
    using _type1 = double;
    using _type2 = short;
};

I want to make the typelist of nested types from TL , something like :

using TL = type_list<Exp1, Exp2>;
using TL2 = type_list<TL::type1...>; // type_list<float, double>

but I can't expand TL as it's not an unexpanded parameter pack.

I've thought about index_sequence but can't manage to make it work.

The question is seemingly looking for map , also called transform in C++. TL is one list of types, and the desire is to apply some type-level function (extract ::type1) and have another list of types. Writing transform is straightforward:

template <template <typename> typename fn, typename TL>
struct type_list_transform_impl;

template <template <typename> typename fn, typename... Ts>
struct type_list_transform_impl<fn, type_list<Ts...>>
{
  using type = type_list<fn<Ts>...>;
};

template <template <typename> typename fn, typename TL>
using type_list_transform = type_list_transform_impl<fn, TL>::type;

And then the type-level function:

template <typename T>
using type1_of = typename T::type1;

And combine the pieces to get TL2:

using TL2 = type_list_transform<type1_of, TL>; // type_list<float, double>

Example: https://godbolt.org/z/b7TMoac5c

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM