【问题标题】:What is a view_closure in range-v3?range-v3 中的 view_closure 是什么?
【发布时间】:2021-07-04 06:18:34
【问题描述】:

在这样的情况下:

auto pow = [](int i) {return i * i; };
auto closure = ranges::views::transform(pow);

closure 似乎是view_closure。我确实明白最后一行没有多大意义,因为变换没有应用到任何地方。 实际上,我也可以通过管道将向量 x 导入到 closure 中,它既可以编译又可以正常工作

但是,什么是 视图闭包?它是一个期望在某处应用的“类似函数”的对象吗?它的语义是什么?

我从 Eric Niebler 的 range-v3 源代码中找到了 this,但没有任何文档在其他地方指定它。

我什至不知道view_closure 是供内部使用还是供用户使用。

【问题讨论】:

    标签: c++ c++20 range-v3 std-ranges


    【解决方案1】:

    range-v3 中的 view_closure 类模板是 C++20 中成为 range adaptor closure object 概念的实现策略:

    范围适配器闭包对象是一个接受viewable_range参数并返回view的一元函数对象。对于范围适配器闭包对象C 和表达式R 使得decltype((R)) 模型viewable_­range,以下表达式是等效的并产生一个视图:

    C(R)
    R | C
    

    给定一个额外的范围适配器闭包对象D,表达式C | D 是格式良好的,并产生另一个范围适配器闭包对象,因此以下两个表达式是等价的:

    R | C | D
    R | (C | D)
    

    transform(f) 的结果是一个范围适配器闭包对象,您可以通过管道作为r | transform(f) 或通过调用作为transform(f)(r) 将其应用于viewable_range,其中任何一个都会为您提供某种@ 987654337@适配器。

    更广泛地说,transform 本身是一个 范围适配器对象,它的定义方式使得 transform(f) 为您提供了一个范围适配器闭包对象,例如 transform(r, f)r | transform(f)、和transform(f)(r) 都是等价的。

    view_closure,类模板,对于确保这样的东西有效:

    auto adaptor = transform(f) | filter(g) | chunks(n);
    

    也就是说,您可以在没有范围的情况下构建管道,其结果是范围适配器闭包对象,然后您可以将其应用于范围 - r | adaptor 将等效于 r | transform(f) | filter(g) | chunks(n) 等价于到chunks(filter(transform(r, f), g), n)

    该类模板基本上会影响operator| 所做的事情,等等。只有在创建自己的范围适配器时才需要使用它,否则作为范围用户不需要关心它。

    【讨论】:

    • 我认为您正在验证我的观点。你的回答太棒了!万分感谢!我需要你提供的标准洞察力:)
    【解决方案2】:

    view_closure 不是一个类型,它是一个模板。该表达式的确切类型是具有未命名闭包类型(即decltype(pow))的该模板的实例化。这是一个实现细节。

    【讨论】:

    • 谢谢。我这边的措辞不好。我想那么问题就变成了:这个模板实现了哪些类型和要求?
    • @giannisgonidelis iirc 它可以是operator| 的右侧,从而产生一个范围对象,当遍历该对象时,它会将变换应用于|ed 范围内的元素。
    猜你喜欢
    • 2016-06-07
    • 2019-11-10
    • 2020-08-25
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    相关资源
    最近更新 更多