我可以管道到范围 v3 累积吗?

Can I pipe to range-v3 accumulate?

本文关键字:v3 管道 范围 我可以      更新时间:2023-10-16

我发现了 3 年前的旧问题,这些问题说一般来说这是不可能的,但我真的很想通过管道来积累,因为它在某些情况下非常好,例如这个:

const double val = data | transform(...) | accumulate (...);

所以我想知道是否在 range-v3/C++20 范围内添加了某些东西,使我能够做到这一点。

No.

您唯一可以输入的是范围适配器 - 接受范围并产生范围的算法。接受范围并返回单个对象(也称为同形(的算法在范围 v3 或 C++20 范围内不可管道化。

你必须这样写:

const double val = accumulate(data | transform(...));

至于为什么accumulate和类似的算法很难|。考虑到我们希望algo(rng, x)rng | algo(x)具有相同的含义。此外,考虑到"总调用"algo(rng, x)可以完全约束(因为您拥有所有信息(,而"部分调用"algo(x)基本上必须在除极少数情况下完全不受约束......基本上大致服用auto&&...

问题是,当第二个参数x也可以是一个范围时,我们必然会遇到歧义。您如何区分意图是全部调用还是部分调用?

下面是一个使用string的示例:

accumulate("hello"s, ""s)

这是一个总调用,它使用默认的二进制运算符+- 即字符串合并。这样做是遍历chars 范围的元素,并将它们一一添加到初始空字符串中。这是一种低效但正确的复制string的方法。您最终得到的值"hello"s.

它的等效管道版本呢?

"hello"s | accumulate(""s)

右侧是什么意思?accumulate(""s)可以算是总通话吗?是的,可以!默认的第二个参数将char(),默认的第三个参数将plus(),这工作正常,因此accumulate(""s)的值是整数0- 使整个表达式格式不正确,因为没有operator|(string, int)

你如何用accumulate做到这一点?