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

时间:2015-11-12 18:56:08

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

如果我有变体,就像这样:

Bitmap

是否有一种简单的方法可以将变量可以包含的类型提取到Boost.Hana元组中,以便以下内容成立:

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

3 个答案:

答案 0 :(得分:7)

以下内容适用于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>, "");

e13d826所做的是添加对mpl::list的支持;之前仅支持mpl::vectorboost::variant<>::typesmpl::list。这就是我的回答需要一段时间的原因;我正在实施: - )。

修改

我没有解释为什么我使用constexpr auto my_tuple = ...代替using my_tuple = decltype(...)。嗯,原因很简单,因为知道my_tuple的类型并不是真的有用,因为你不能依赖它。实际上,如果你看一下hana::type的文档,就会写出你不能依赖hana::type<T>任何特定的文档。这有很好的理由,但从可用性的角度来看,这意味着你不能依赖于hana::tuple<hana::type<...>, ...>的类型。在进行类型级计算时,首选值级编码(因此auto my_tuple = ...)进行类型级编码。这是Hana对MPL&amp; amp;的特异性。朋友们,你们应该尽可能地坚持下去,否则你会发现Hana真的很笨重(因为没有记住这一点)。

答案 1 :(得分:2)

这并没有使用任何hana功能,但应该可以使用。

首先,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...>;
};

现在,这是一个获取类型的模板,并返回hana类型的hana元组:

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

我们完成了:

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

using result = get_types_from< my_variant >;

get_types_from是因为提取任意模板的模板参数的类型函数似乎很有用。

答案 2 :(得分:2)

一段时间以来,我遇到了类似于这种转换的事情。虽然不能找到这个想法的实际来源,或者甚至可能是一种非常普遍的做法:

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;

因为,我不确定提升hana元组,我将用std :: tuple显示一个例子

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