Search code examples
c++c++11templatesvariadic-templatesstdtuple

Transform std::pair to std::tuple with any number of elements


I need the following meta code adapted from std::pair to std::tuple with any number of elements. I don't want to implement it separately for every possible number of elements.

template<typename A, typename B>
struct merge_pairs
{       typedef std::pair<
            decltype(typename A::first() + typename B::first()),
            decltype(typename A::second() + typename B::second())
        > type;
};

Solution

  • Option #1

    #include <cstddef>
    #include <type_traits>
    #include <utility>
    #include <tuple>
    
    template <typename A, typename B>
    struct merge_tuples
    {
        static_assert(std::tuple_size<A>::value == std::tuple_size<B>::value, "!");
    
        template <std::size_t... Is>
        static auto merge(std::index_sequence<Is...>) noexcept
            -> std::tuple<typename std::decay<decltype(std::declval<typename std::tuple_element<Is, A>::type>()
                                                     + std::declval<typename std::tuple_element<Is, B>::type>())
                                   >::type...>;
    
        using type = decltype(merge(std::make_index_sequence<std::tuple_size<A>::value>{}));    
    };
    

    DEMO

    Option #2

    #include <type_traits>
    #include <utility>
    
    template <typename A, typename B>
    struct merge_tuples;
    
    template <template <typename...> class Tuple, typename... Ts, typename... Us>
    struct merge_tuples<Tuple<Ts...>, Tuple<Us...>>
    {
        static_assert(sizeof...(Ts) == sizeof...(Us), "!");
    
        using type = Tuple<typename std::decay<decltype(std::declval<Ts>()
                                                      + std::declval<Us>())
                                    >::type...>;
    };
    

    DEMO 2