【问题标题】:Extracting a tuple of value_type from a tuple of containers in C++11从 C++11 中的容器元组中提取 value_type 元组
【发布时间】:2016-03-12 13:48:39
【问题描述】:

我有一个带有模板参数的函数,我知道它是几个不同元素类型的标准 C++ 容器的std::tuple。 如何从中提取元素类型的 std::tuple 类型?

例如,假设我有以下函数

template <typename TupOfCtrs>
void doStuff(const TupOfCtrs& tupOfCtrs) {
    using TupOfElements = /*extract a tuple type by applying CtrT::value_type to each container in tupOfCtrs and combining the results into an std::tuple*/;
    MyHelperClass<TupOfElements> helper;
}

我知道它是这样称呼的:

std::list<Foo> l {/*...*/};
std::vector<Bar> v {/*...*/};
std::deque<Baz> d {/*...*/};
auto tup = std::make_tuple(l, v, d);

在这种情况下,我希望将 TupOfElements 帮助器类型定义为 std::tuple&lt;Foo, Bar, Baz&gt;。 请注意,我不需要实际创建元组,只需获取其类型即可。

如何实现,可能使用Boost::Fusion 库?

【问题讨论】:

    标签: c++ templates c++11 boost boost-fusion


    【解决方案1】:

    您甚至可以在没有 Boost Fusion 的情况下以更简单的方式执行此操作,如下所示:

    // Template which takes one type argument:
    template <typename Tuple> struct TupOfValueTypes;
    
    // Only provide a definition for this template for std::tuple arguments:
    // (i.e. the domain of this template metafunction is any std::tuple)
    template <typename ... Ts>
    struct TupOfValueTypes<std::tuple<Ts...> > {
        // This definition is only valid, if all types in the tuple have a
        // value_type type member, i.e. the metafunction returns a type only
        // if all types of the members in the std::tuple have a value_type
        // type member, and a std::tuple can be constructed from these:
        using type = std::tuple<typename Ts::value_type...>;
    };
    
    template <typename TupOfCtrs>
    void doStuff(const TupOfCtrs& tupOfCtrs) {
        using TupOfElements = typename TupOfValueTypes<TupOfCtrs>::type;
        // ...
    }
    

    但是为std::tuple明确指定doStuff当然更容易:

    template <typename ... Ts>
    void doStuff(const std::tuple<Ts...> & tupOfCtrs) {
        using TupOfElements = std::tuple<typename Ts::value_type...>;
        // ...
    }
    

    PS:另外请注意,在许多情况下,如果您只需要一个类型列表,std::tuple 类是多余的,并且可能会稍微缩短编译时间。就个人而言,我一直使用简单的 TypeList 结构:

    template <typename ... Ts> struct TypeList
    { using type = TypeList<Ts...>; };
    

    【讨论】:

      【解决方案2】:

      如果您希望 doStuff 使用 std::tuple,请明确说明:

      template <class... Ts>
      void doStuff(std::tuple<Ts...> const& tupOfCtr) { ... }
      

      一旦你有了那个参数包,只需拔出value_type

      template <class... Ts>
      void doStuff(std::tuple<Ts...> const& tupOfCtr)
      {
          using value_tuple = std::tuple<typename Ts::value_type...>;
          // ...
      }
      

      【讨论】:

        猜你喜欢
        • 2018-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        相关资源
        最近更新 更多