我发现了 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)
这是一个总调用,它使用默认的二进制运算符+
- 即字符串合并。这样做是遍历char
s 范围的元素,并将它们一一添加到初始空字符串中。这是一种低效但正确的复制string
的方法。您最终得到的值"hello"s
.
它的等效管道版本呢?
"hello"s | accumulate(""s)
右侧是什么意思?accumulate(""s)
可以算是总通话吗?是的,可以!默认的第二个参数将char()
,默认的第三个参数将plus()
,这工作正常,因此accumulate(""s)
的值是整数0
- 使整个表达式格式不正确,因为没有operator|(string, int)
。
你如何用accumulate
做到这一点?