如何将 boost::hana::tuple 转换为 std::variant
Posted
技术标签:
【中文标题】如何将 boost::hana::tuple 转换为 std::variant【英文标题】:How to convert a boost::hana::tuple into a 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
,结果相同。
【问题讨论】:
【参考方案1】:我建议在您的代码中进行三处更正(两个已在另一个答案中解决):
使用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;
【讨论】:
【参考方案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<decltype(my_tuple)>
。
基本上,我们首先解开所有类型(这使我们从 hana::tuple<hana::type_impl<int>::_, hana::type_impl<char>::_, ...>
之类的东西变成了 hana::tuple<int, char, ...>
),然后我们将***模板从 hana::tuple
重命名为 std::variant
。
【讨论】:
以上是关于如何将 boost::hana::tuple 转换为 std::variant的主要内容,如果未能解决你的问题,请参考以下文章