我以前曾经使用过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版本给了我一个不能成为类成员的变量,而且我似乎也不能用来使它成为类成员。一种类型。
答案 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();
}