【问题标题】:Why is `boost::hana::range_c` not a Sequence?为什么`boost::hana::range_c`不是序列?
【发布时间】:2016-01-15 15:56:41
【问题描述】:
#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");
}

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

【问题讨论】:

    标签: c++ boost-hana


    【解决方案1】:

    首先,有几种解决方案:

    解决方案 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) 之间选择您喜欢的任何一个,它们实际上是等效的。

    现在,ranges 不模仿 Sequence 概念的原因是因为那没有意义。 Sequence 概念要求我们能够使用hana::make 函数创建任意Sequence。因此,对于任何Sequence 标签Shana::make&lt;S&gt;(...) 必须创建包含... 的标签SSequence。但是,range 必须在某个时间间隔内包含连续的 integral_constants。因此,如果rangeSequence,则hana::make&lt;hana::range_tag&gt;(...) 应该包含... 是什么,如果... 不是连续的integral_constants,这会破坏range 的不变量。例如考虑

    hana::make<hana::range_tag>(hana::int_c<8>, hana::int_c<3>,
                                hana::int_c<5>, hana::int_c<10>)
    

    这应该是一个包含integral_constants 8,3,5,10range,这是没有意义的。另一个类似的例子说明了为什么range 不能是Sequencepermutations 算法。 permutations 算法采用 Sequence 并返回包含所有排列的 Sequences 的 Sequence。显然,由于range 只能容纳integral_constants,因此尝试创建ranges 的range 是没有意义的。这样的例子比比皆是。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      • 2016-07-31
      相关资源
      最近更新 更多