[英]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.