【问题标题】:Expand a tuple TYPE into a variadic template?将元组 TYPE 扩展为可变参数模板?
【发布时间】:2020-02-11 12:43:49
【问题描述】:

我有一个函数main_func,我通过将参数包/可变参数模板转换为元组来修改它。我修改后,例如:original = tuple<int, float, string>变成modified = tuple<int float>我想将修改后的元组扩展为示例get_type_vector中的另一个函数,以便参数包代表修改后的元组Args = int, float的类型。

template<typename... Args>
void main_func()
{
    // Modify the parameter pack (which if im correct can only be done by converting to tuple?)
    using original = std::tuple<Args...>;
    using modified = // something that alters the types of the original tuple

    // This is what i want to accomplish
    // somehow expand the tuple type like a parameter pack
    auto vec = get_type_vector<modified...>()
}

// Returns a vector of type_info
template<typename... Args>
std::vector<type_info> get_type_vector()
{
    return { type_info<Args>()... };
}

是否可以像参数包的类型一样扩展元组类型?我找到了使用 std::apply 等的示例,但这需要您有一个值,而不仅仅是元组的 typedef。

【问题讨论】:

    标签: c++ tuples metaprogramming variadic-templates typetraits


    【解决方案1】:

    您可以通过引入间接层轻松扩展元组,该层可以是 lambda (C++20) 或模板函数 (C++11)。例如

    std::tuple<int, float, char> t;
    []<typename... Ts>(std::tuple<Ts...>)
    {
        // use `Ts...` here
    }(t);
    

    在你的情况下:

    template <typename T>
    struct type_wrapper { using type = T; };
    
    template<typename... Args>
    std::vector<type_info> get_type_vector(type_wrapper<std::tuple<Args...>>)
    {
        return { type_info<Args>()... };
    }
    
    get_type_vector(type_wrapper<std::tuple<int, float, char>>{});
    

    type_wrapper 类可防止在运行时对元组进行无用的实例化。你可以在 C++20 中使用std::type_identity

    【讨论】:

      【解决方案2】:

      一个相当简单的方法是重载并让编译器推断类型。 std::type_identity 在这里很有用(C++20,但很容易在任何版本的 C++ 中复制)。它可以根据类型创建简单的廉价标签

      template<typename... Args>
      std::vector<type_info> get_type_vector(std::type_identity<std::tuple<Args...>>)
      {
          return { type_info<Args>()... };
      }
      

      使用它就是写

      auto vec = get_type_vector(std::type_identity<modified>{})
      

      【讨论】:

        猜你喜欢
        • 2010-10-15
        • 1970-01-01
        • 2017-05-28
        • 2014-04-12
        • 2014-10-30
        • 2013-10-03
        相关资源
        最近更新 更多