Creating a sub-tuple starting from a std::tuple

前端 未结 4 1500
深忆病人
深忆病人 2021-01-18 18:29

Let us suppose that a std::tuple is given. I would like to create a new std::tuple whose types are the ones indexed in [

4条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-18 18:40

    This kind of manipulation is fairly easy with an index sequence technique: generate an index sequence with two fewer indices than your tuple, and use that sequence to select fields from the original. Using std::make_index_sequence and return type deduction from C++14:

    template 
    auto subtuple_(const std::tuple& t, std::index_sequence) {
      return std::make_tuple(std::get(t)...);
    }
    
    template 
    auto subtuple(const std::tuple& t) {
      return subtuple_(t, std::make_index_sequence());
    }
    

    In C++11:

    #include      // for std::size_t
    
    template
    struct integer_sequence {
      using value_type = T;
    
      static constexpr std::size_t size() noexcept {
        return sizeof...(I);
      }
    };
    
    namespace integer_sequence_detail {
    template  struct concat;
    
    template 
    struct concat, integer_sequence> {
      typedef integer_sequence type;
    };
    
    template 
    struct build_helper {
      using type = typename concat<
        typename build_helper::type,
        typename build_helper::type
      >::type;
    };
    
    template 
    struct build_helper {
      using type = integer_sequence;
    };
    
    template 
    struct build_helper {
      using type = integer_sequence;
    };
    
    template 
    using builder = typename build_helper::type;
    } // namespace integer_sequence_detail
    
    template 
    using make_integer_sequence = integer_sequence_detail::builder;
    
    template 
    using index_sequence = integer_sequence;
    
    template
    using make_index_sequence = make_integer_sequence;
    
    #include 
    
    template 
    auto subtuple_(const std::tuple& t, index_sequence) 
      -> decltype(std::make_tuple(std::get(t)...))
    {
      return std::make_tuple(std::get(t)...);
    }
    
    template 
    auto subtuple(const std::tuple& t)
      -> decltype(subtuple_(t, make_index_sequence()))
    {
      return subtuple_(t, make_index_sequence());
    }
    

    Live at Coliru.

提交回复
热议问题