首先,有几种解决方案:
解决方案 1
auto indices = hana::to<hana::tuple_tag>(hana::range_c<std::size_t, 0, sizeof...(T)>);
auto types = hana::make_tuple(std::forward<T>(args)...);
hana::for_each(hana::zip(indices, types), hana::fuse([](auto i, auto&& x) {
// ...
}));
解决方案 2
auto indices = hana::range_c<std::size_t, 0, sizeof...(T)>;
auto types = hana::make_tuple(std::forward<T>(args)...);
hana::for_each(indices, [&](auto i) {
auto& x = types[i];
// ...
});
解决方案 3
auto types = hana::make_tuple(std::forward<T>(args)...);
hana::size_c<sizeof...(T)>.times.with_index([&](auto i) {
auto& x = types[i];
// ...
});
解决方案(1)的缺点是复制每个args
,因为zip
返回一个序列序列,而 Hana 中的所有内容都是按值计算的。由于这可能不是您想要的,您应该在解决方案(2)和(3)之间选择您喜欢的任何一个,它们实际上是等效的。
现在,range
s 不为这个Sequence
概念建模的原因是因为那没有意义。该Sequence
概念要求我们能够Sequence
使用该hana::make
函数创建任意值。因此,对于任何Sequence
标签S
,hana::make<S>(...)
必须创建一个包含Sequence
的标签。但是,a必须在某个区间内包含连续的 s。因此,如果是 a ,应该包含什么是,这打破了 a if are not contiguous s 的不变量。考虑例如S
...
range
integral_constant
range
Sequence
hana::make<hana::range_tag>(...)
...
range
...
integral_constant
hana::make<hana::range_tag>(hana::int_c<8>, hana::int_c<3>,
hana::int_c<5>, hana::int_c<10>)
这应该是一个range
包含integral_constant
s 的8,3,5,10
内容,这没有意义。另一个类似的例子说明为什么 arange
不能是 aSequence
是permutations
算法。该permutations
算法采用 aSequence
并返回包含所有排列的a Sequence
of s。Sequence
显然,由于 arange
只能持有s,因此尝试创建 a of sintegral_constant
是没有意义的。这样的例子比比皆是。range
range
换句话说,range
s 过于专业化,无法对Sequence
概念进行建模。拥有这样一个专门的结构的好处是它在编译时非常高效。缺点是它不是通用容器,不能在上面进行一些操作(比如zip
)。但是,range
如果您知道权衡是什么,您完全可以将其转换为完整的序列。