【问题标题】:How to convert a boost::hana::tuple into a std::variant如何将 boost::hana::tuple 转换为 std::variant
【发布时间】:2020-05-19 06:46:12
【问题描述】:

我有以下代码,我想将boost::hana::tuple 转换为std::variant

namespace hana = boost::hana;

template <typename Tuple>
struct to_variant;

template <typename... Ts>
struct to_variant<std::tuple<Ts...>>
{
    using type = std::variant<Ts...>;
};

auto my_tuple = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<float>);

using my_variant = typename to_variant<my_tuple>::type;

但我总是收到错误消息

error: type/value mismatch at argument 1 in template parameter list for 'template<class Tuple> struct to_variant'
using my_variant = typename to_variant<my_tuple>::type;

我尝试将std::tuple 替换为hana::tuple,结果相同。

【问题讨论】:

    标签: c++ c++17 template-meta-programming boost-hana


    【解决方案1】:

    我建议在您的代码中进行三处更正(两个已在另一个答案中解决):

    • 使用decltype(my_tuple)类型 传递给to_variant
    • to_variant 内部,使用using type = std::variant&lt;typename Ts::type...&gt; 将类型从Hana type_c 中提取出来。
    • 在专业化中使用hana::tuple,而不是std::tuple。更一般地说,您还可以在此处使用模板模板参数。

    下面是对应的代码:

    namespace hana = boost::hana;
    
    template <typename Tuple>
    struct to_variant;
    
    template <typename... Ts>
    struct to_variant<hana::tuple<Ts...>>
    {
        using type = std::variant<typename Ts::type...>;
    };
    
    auto my_tuple = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<float>);
    
    using my_variant = typename to_variant<decltype(my_tuple)>::type;
    

    【讨论】:

      【解决方案2】:

      my_tuple 是一个对象,但不是 type。 (并且它的类型不是std::tuple,而是boost::hana::tuple,应该用于专业化。)

      我想你想要

      template <typename Tuple>
      struct to_variant;
      
      template <typename... Ts>
      struct to_variant<boost::hana::tuple<Ts...>>
      //                ^^^^^^^^^^^^^^^^^^
      {
          using type = std::variant<Ts...>;
      };
      
      auto my_tuple = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<float>);
      
      using my_variant = typename to_variant<decltype(my_tuple)>::type;
      //                                     ^^^^^^^^^        ^
      

      【讨论】:

      • 嗯,这很容易......但我现在可能在我的变体中输入了 hana::type_c 类型?
      • @davidhigh 我的设置有点复杂,我的元组类型来自hana的一些类型计算,因此我必须使用hana::type_c我猜...
      【解决方案3】:

      对于Boost.Mp11,这很短(一如既往):

      template <typename T> using unwrap = typename T::type;
      
      template <typename T>
      using to_variant = mp_rename<mp_transform<unwrap, T>, std::variant>;
      

      您将在哪里使用它作为to_variant&lt;decltype(my_tuple)&gt;

      基本上,我们首先解开所有类型(这使我们从 hana::tuple&lt;hana::type_impl&lt;int&gt;::_, hana::type_impl&lt;char&gt;::_, ...&gt; 之类的东西变成了 hana::tuple&lt;int, char, ...&gt;),然后我们将顶级模板从 hana::tuple 重命名为 std::variant

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多