如何使用Boost.Hana

时间:2018-08-14 21:19:22

标签: c++ c++14 boost-hana

我以前曾经使用过Boost.MPL库的一点点,而我试图更多地了解Boost.Hana。我似乎对图书馆完全误解了。

我想使用任意数量的模板参数实例化一个对象,基于这些类型创建一个对象元组作为成员,然后迭代或稍后使用该元组。

我遇到的是,所有示例和文档仅涉及在函数中创建元组,而不是实际生成可用于类成员的类型。

这是我要执行的操作的简化示例:

template<typename T>
struct Bar { void apply() const {} };

template<typename ...T>
struct Foo
{
   template<typename _T>
   using Bar = Bar<_T>;

   static constexpr auto tuple = boost::hana::transform(
      boost::hana::tuple_t<T...>,
      boost::hana::template_<Bar>);

   void apply()
   {
      boost::hana::for_each(
         tuple,
         [](auto const& bar)
         {
            bar.apply();
         });
   }
};

我得到的错误:

error: 'const struct boost::hana::type_impl<Bar<int> >::_' has no member named 'apply'

所以元组不包含Bar<T>类型的对象,而包含boost :: hana“代表类型的对象”类型的对象。

我可以像这样制作一个元组:

boost::hana::tuple<T...> m_tuple;

我已经很接近想要的东西了,但是如何将boost::hana::transform集成到m_tuple的声明中?

我不知道如何从boost::hana::transform返回的变量变成我可以用于该类成员的类型。这有可能吗?还是应该看Boost.MPL?

我确实见过a presentation given at cppnow 2017,其中有一个从MPL转到Hana的示例:

MPL

using Ptrs = mpl::transform<Types, std::add_pointer<mpl::_1>>::type;
// -> mpl::vector<int*, void*, char*, long*, void*>

Hana

auto Ptrs = hana::transform(Types, [](auto t) {
   return hana::traits::add_pointer(t);
});
// -> hana::tuple_t<int*, void*, char*, long*, void*>

但是MPL版本给了我一种我可以用来成为类成员的类型,而Hana版本给了我一个不能成为类成员的变量,而且我似乎也不能用来使它成为类成员。一种类型。

1 个答案:

答案 0 :(得分:1)

答案是hana::tuple_t是元组的别名,其中所有成员都包裹在hana::type中。

注释中链接的答案是一个很好的解决方案,但这是一个使MPL样式模板元编程更进一步的示例。它更加简洁,并且没有掩盖它依赖默认构造的事实。

#include <boost/hana.hpp>

namespace hana = boost::hana;

template <typename T>
struct Bar { void apply() const { } };

template <typename ...T>
struct Foo
{
  void apply()
  {
    hana::for_each(
      hana::tuple<Bar<T>...>{},
      [](auto const& bar)
      {
        bar.apply();
      });
  }
};

int main()
{
  Foo<int, float, char>{}.apply();
}