简体   繁体   English

Hana:如何从变体中创建类型元组?

[英]Hana: How do I create a tuple of types from a variant?

If I have a variant, like so: 如果我有变体,就像这样:

using my_variant = boost::variant<int, bool, std::string>;

Is there an easy way to extract the types the variant can contain into a Boost.Hana tuple so that the following holds: 有没有一种简单的方法可以将变量可以包含的类型提取到Boost.Hana元组中,以便满足以下条件:

using boost::hana::type;
static_assert(std::is_same<my_tuple, boost::hana::tuple<type<int>, type<bool>, type<std::string>>>{});

The following will work on develop (since e13d826 ): 以下将适用于develop (自e13d826 ):

#include <boost/hana.hpp>
#include <boost/hana/ext/boost/mpl.hpp>
#include <boost/variant.hpp>
#include <string>
namespace hana = boost::hana;


using my_variant = boost::variant<int, bool, std::string>;

constexpr auto my_tuple = hana::to<hana::tuple_tag>(my_variant::types{});

// Note:
// In general, don't use std::is_same to compare hana::tuple; use == in
// because it will also work if the tuple contains hana::basic_types.
static_assert(my_tuple == hana::tuple_t<int, bool, std::string>, "");

What e13d826 did was add support for mpl::list ; e13d826的作用是添加对mpl::list支持; only mpl::vector was supported before, and boost::variant<>::types is a mpl::list . 之前只支持mpl::vector ,而boost::variant<>::types是一个mpl::list This is why my answer took a while to come; 这就是我的回答需要一段时间的原因; I was implementing that :-). 我正在实施:-)。

Edit 编辑

I did not explain why I'm using constexpr auto my_tuple = ... instead of using my_tuple = decltype(...) . 我没有解释为什么我使用constexpr auto my_tuple = ...而不是using my_tuple = decltype(...) Well, the reason is simply because knowing the type of my_tuple is not really useful, since you can't rely on it. 嗯,原因很简单,因为知道my_tuple的类型并不是很有用,因为你不能依赖它。 Indeed, if you look at the documentation of hana::type , it's written that you can't rely on hana::type<T> being anything specific. 实际上,如果你看一下hana::type的文档,那就写出你不能依赖hana::type<T>是什么特定的。 There are good reasons for this, but from a usability point of view it means that you can't rely on the type of hana::tuple<hana::type<...>, ...> being anything specific either. 这有很好的理由,但从可用性的角度来看,它意味着你不能依赖于hana::tuple<hana::type<...>, ...> When doing type-level computations, prefer value-level encoding (thus auto my_tuple = ... ) to type-level encoding. 在进行类型级计算时,首选值级编码(因此auto my_tuple = ... )进行类型级编码。 This is the specificity of Hana over MPL & friends, and you should try to stick with it as much as possible, or you'll find Hana to be really clunky (because not written with that in mind). 这是Hana对MPL和朋友的特殊性,你应该尽可能地坚持下去,否则你会发现Hana真的很笨重(因为没有考虑到这一点)。

This doesn't use any hana features, but should work. 这不使用任何hana功能,但应该工作。

First, a transcribe type function that takes a template, and an instance of a different template, and transcribes the types in the second into the first: 首先, transcribe类型函数采用模板和不同模板的实例,并将第二类中的类型转录为第一类:

template<template<class...>class To, class From>
struct transcribe;
template<template<class...>class To, class From>
using transcribe_t=typename transcribe<To,From>::type;

template<template<class...>class Z, template<class...>class Src, class...Ts>
struct transcribe<Z, Src<Ts...>> {
  using type=Z<Ts...>;
};

Now, a template that takes types, and returns a hana tuple of hana types: 现在,一个模板,它接受类型,并返回hana元组的hana元组:

template<class...Ts>
using tuple_of_types = boost::hana::tuple<boost::hana::type<Ts>...>;

And we are done: 我们完成了:

template<class Src>
using get_types_from = transcribe_t< tuple_of_types, Src >;

using result = get_types_from< my_variant >;

get_types_from is because a type function that extracts the template arguments of an arbitrary template seems useful. get_types_from是因为提取任意模板的模板参数的类型函数似乎很有用。

Some time back I had come across something similar to this for such conversion. 一段时间以来,我遇到了类似于这种转换的东西。 Not able to find the actual source of this idea though or it may be even a pretty common practice: 虽然无法找到这个想法的实际来源,但它甚至可能是一个非常常见的做法:

template<class From, template<class...> class To> struct convert_impl;

template<template<class...> class From, class... Types, 
         template<class...> class To>
struct convert_impl<From<Types...>, To>
{
    using converted_type = To<Types...>;
};

template<class From, template<class...> class To>
using convert = typename convert_impl<From, To>::converted_type;

Since, I am not sure about boost hana tuple, I will show an example with std::tuple 因为,我不确定提升hana元组,我将展示一个std :: tuple的例子

convert<boost::variant<int, bool, string>, std::tuple>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 boost::hana::tuple 转换为 std::variant - How to convert a boost::hana::tuple into a std::variant 如何根据Boost.Hana中的表达式是否有效来过滤类型的元组? - How do I filter a tuple of types depending on whether an expression is valid in Boost.Hana? 创建具有不可移动/不可复制类型的汉娜元组 - Create hana tuple with unmovable / noncopyable types 将hana :: tuple中的类型转换为std :: vector <type> 在一个hana :: tuple中 - Convert types in hana::tuple to std::vector<type> within a hana::tuple 如何在变体中的类型上使用 map 包装器类型 - How do I map a wrapper type over the types in a variant 如何从可变参数模板参数创建 std::tuple&lt;&gt;? - How do I create an std::tuple<> from a variadic template parameter? 在没有预处理器的情况下从hana元组创建函数签名 - Create a function signature from a hana tuple without the preprocessor 从hana :: tuple_t到hana :: tuple - Going from hana::tuple_t to hana::tuple 如何防止将隐式转换为具有多种整数类型的boost :: variant类型? - How do I prevent implict conversion to boost::variant types with multiple types of integers? 如何将元组 &lt;&gt; 剥离回可变参数模板类型列表? - How do I strip a tuple<> back into a variadic template list of types?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM