2

在这样的情况下:

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

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

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

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

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

4

2 回答 2

4

range-v3 中的view_closure类模板是 C++20 中成为范围适配器闭包对象概念的实现策略:

范围适配器闭包对象是一个一元函数对象,它接受一个viewable_range参数并返回一个view. 对于范围适配器闭包对象CR诸如decltype((R))models的表达式viewable_­range,以下表达式是等价的并产生一个视图:

C(R)
R | C

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

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

的结果transform(f)是一个范围适配器闭包对象,您可以将其应用于viewable_rangevia pipe asr | transform(f)或 via call as transform(f)(r),其中任何一个都会为您提供某种transform_view适配器。

更广泛地说,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|所做的事情。只有在创建自己的范围适配器时才需要使用它,否则作为范围用户不需要关心它。

于 2021-04-08T19:29:06.080 回答
1

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

于 2021-04-08T11:43:47.743 回答