我之前问过一个关于创建编译时列表数据结构的问题,建议使用 Boost.hana
我试过这个基本的测试代码:
#include <boost/hana/tuple.hpp>
#include <boost/hana/for_each.hpp>
#include <boost/hana/concat.hpp>
#include <iostream>
namespace hana = boost::hana;
template<typename A, typename R>
constexpr R parse(A count)
{
if(count == 0)
{
return hana::make_tuple(0);
}
else
{
return parse(count - 1);
}
}
int main()
{
constexpr auto l = parse(10);
hana::for_each
(
l,
[](auto const& element)
{
std::cout << element << std::endl;
}
);
}
但是,模板类型推导不起作用,因为每次调用递归函数都会返回不同的类型。 有没有解决的办法?
最佳答案
在使用 hana 进行元编程时,您必须了解的主要事情是没有值 - 我们不是在操纵数字之类的东西,而是在操纵类型。这些类型可能有与之关联的值,但它们仍然是类型。术语是 IntegralConstant .
你想要的是这样的:
template <class C>
constexpr auto parse(C count)
{
if constexpr(count == 0_c) {
return hana::tuple(count);
} else {
return hana::flatten(hana::make_tuple(
hana::tuple(count),
parse(count - 1_c)));
}
}
constexpr auto l = parse(10_c);
10_c
是 IntegralConstant 的实例,其值为 10
.我们可以将其与 0_c
进行比较在基本情况下。这看起来像是值相等,这是使用 Hana 的真正好处,但它不是值相等——它纯粹是基于类型的。
parse(10_c)
的结果是相当于 <10,9,8,7,6,5,4,3,2,1,0>
的编译时元组.
请注意:
template<typename A, typename R>
constexpr R parse(A count);
不是一个特别有用的函数模板,因为 R
是非推导上下文,因此必须在调用站点指定。 parse(10)
无论parse()
的正文如何,都是不合格的.
关于c++ - 如何使用 Boost hana 递归创建 constexpr 列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45150656/