为什么`boost :: hana :: range_c`不是序列?

Bri*_*uez 5 c++ boost-hana

#include <string>
#include <utility>
#include <vector>
#include <boost/hana.hpp>
namespace hana = boost::hana;

template <typename ...T>
void indexed_T_work(T&& ...args)
{
    auto indices = 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)
      , [](auto&& pair_) { /* Do index-dependent work with each `T` */ }
        );
}

int main()
{
    indexed_T_work(5, 13, std::vector<std::string>{}, 32.f, 42, "foo");
}
Run Code Online (Sandbox Code Playgroud)

我想用hana::zipa hana::tuplehana::range_c,但hana::range_c不被认为是一个序列,这是一个要求hana::zip.这个决定背后的原因是什么?我如何(惯用)在尊重这个决定的同时实现我的目标?

Lou*_*nne 8

首先,有几种解决方案:

解决方案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) {
    // ...
}));
Run Code Online (Sandbox Code Playgroud)

解决方案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];
    // ...
});
Run Code Online (Sandbox Code Playgroud)

解决方案3

auto types = hana::make_tuple(std::forward<T>(args)...);
hana::size_c<sizeof...(T)>.times.with_index([&](auto i) {
    auto& x = types[i];
    // ...
});
Run Code Online (Sandbox Code Playgroud)

解决方案(1)的缺点是制作每个的副本args因为zip返回一系列序列,而Hana中的所有内容都是按值计算的.由于这可能不是你想要的,你应该在解决方案(2)(3)之间选择你喜欢的,这两者实际上是等价的.

现在,ranges不为这个Sequence概念建模的原因是因为这没有意义.这个Sequence概念要求我们能够Sequence使用该hana::make函数创建任意.因此,对于任何Sequence标记S,hana::make<S>(...)必须创建包含Sequence的标记.但是,必须在某个间隔中包含连续的s.因此,如果是a ,应该包含什么,哪个打破了if 不是连续的s 的不变量.例如,考虑一下S...rangeintegral_constantrangeSequencehana::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>)
Run Code Online (Sandbox Code Playgroud)

这应该是一个range包含integral_constants 8,3,5,10,这是没有意义的.示出为什么另一个类似的例子range不能是Sequencepermutations算法.该permutations算法采用a Sequence并返回包含所有排列SequenceSequences.显然,由于range只能持有integral_constantS,它没有任何意义,试图创建一个rangerange秒.像这样的例子比比皆是.

换句话说,ranges太专业化,无法对Sequence概念进行建模.拥有这样一个专门结构的好处是它具有非常高的编译时间.缺点是它不是一个通用的容器,有些操作不能在它上面完成(比如zip).但是,range如果你知道什么是权衡,你可以完全接受并将其转换为完整的序列.