如何将 boost::hana::tuple 转换为 std::variant

How to convert a boost::hana::tuple into a std::variant

我有以下代码,我想将 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;

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

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;
//                                     ^^^^^^^^^        ^

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

  • 使用decltype(my_tuple)类型传递给to_variant
  • to_variant 中,使用 using type = std::variant<typename Ts::type...> 从 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;

对于 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<decltype(my_tuple)>

基本上,我们首先解包所有类型(这让我们从 hana::tuple<hana::type_impl<int>::_, hana::type_impl<char>::_, ...>hana::tuple<int, char, ...>)然后我们将顶级模板从 hana::tuple 重命名为 std::variant.