Search code examples
c++c++11stdtuple

Removing the first type of a std::tuple


This seems to be a very simple question: How does one remove the first (the n-th) type in a std::tuple?

Example:

typedef std::tuple<int, short, double> tuple1;
typedef std::tuple<short, double> tuple2;

The operation described above would transform tuple1 into tuple2. Is it possible?


Solution

  • You can use a simple type function based on partial specialization of a class template:

    #include <type_traits>
    #include <tuple>
    
    using namespace std;
    
    template<typename T>
    struct remove_first_type
    {
    };
    
    template<typename T, typename... Ts>
    struct remove_first_type<tuple<T, Ts...>>
    {
        typedef tuple<Ts...> type;
    };
    
    int main()
    {
        typedef tuple<int, bool, double> my_tuple;
        typedef remove_first_type<my_tuple>::type my_tuple_wo_first_type;
    
        static_assert(
            is_same<my_tuple_wo_first_type, tuple<bool, double>>::value, 
            "Error!"
            );
    }
    

    Also, this solution can be easily generalized to remove the i-th type of a tuple:

    #include <type_traits>
    #include <tuple>
    
    using namespace std;
    
    template<size_t I, typename T>
    struct remove_ith_type
    {
    };
    
    template<typename T, typename... Ts>
    struct remove_ith_type<0, tuple<T, Ts...>>
    {
        typedef tuple<Ts...> type;
    };
    
    template<size_t I, typename T, typename... Ts>
    struct remove_ith_type<I, tuple<T, Ts...>>
    {
        typedef decltype(
            tuple_cat(
                declval<tuple<T>>(),
                declval<typename remove_ith_type<I - 1, tuple<Ts...>>::type>()
                )
            ) type;
    };
    
    int main()
    {
        typedef tuple<int, bool, double> my_tuple;
        typedef remove_ith_type<1, my_tuple>::type my_tuple_wo_2nd_type;
    
        static_assert(
            is_same<my_tuple_wo_2nd_type, tuple<int, double>>::value, 
            "Error!"
            );
    }