代码之家  ›  专栏  ›  技术社区  ›  efzzz

C++定义给定基元组类型和可变索引序列的子元组类型

  •  0
  • efzzz  · 技术社区  · 2 年前

    假设我有一个元组,例如。 using BaseTuple = std::tuple<int, double, string>; ,我想从给定的可变索引序列中定义新的类型,以及转换到BaseTuple和从BaseTupple转换的方法。例如,CustomTuple<0,1>应该从元组<int,双精度>。

    using BaseTuple = tuple<int, double, string>;
    
    template <size_t... I>
    struct CustomTuple: public tuple<tuple_element_t<I, BaseTuple>...>{
        using tuple<tuple_element_t<I, BaseTuple>...>::tuple;
    
        static CustomTuple fromBaseTuple(const BaseTuple& key){
            return {get<I>(key)...};
        };
    
        BaseTuple toBaseTuple(){
            BaseTuple t;
            ((get<tuple_element_t<I, BaseTuple>>(t) = get<tuple_element_t<I, BaseTuple>>(t)), ...);
            return t;
        }
    };
    
    

    如果元组有唯一的类型,上面的代码就可以工作,但我想知道是否有任何方法可以处理重复的类型。我找不到一种方法来迭代我……用它的索引。

    2 回复  |  直到 2 年前
        1
  •  1
  •   Igor Tandetnik    2 年前

    大致如下:

    template <std::size_t... S>
    BaseTuple toBaseTuple(std::index_sequence<S...>) {
        BaseTuple t;
        ((std::get<I>(t) = std::get<S>(*this)), ...);
        return t;
    }
    BaseTuple toBaseTuple(){
        return toBaseTuple(std::make_index_sequence<sizeof...(I)>{});
    }
    

    Demo

        2
  •  0
  •   Patrick Roberts Benjamin Gruenbaum    2 年前

    你可以使用 std::apply 并且避免了一起查找每个对应元素的需要:

    using type = std::tuple<std::tuple_element_t<I, BaseTuple>...>
    
    constexpr auto toBaseTuple() const {
      BaseTuple to;
      std::apply(
          [&](const auto &...elements) { (..., (std::get<I>(to) = elements)); },
          static_cast<const type &>(*this));
      return to;
    }
    

    Try it on godbolt.org