我可以通过管道传输到 range-v3 accumulate 吗?
Can I pipe to range-v3 accumulate?
我发现 3 年前的旧问题说一般来说这是不可能的,但我真的很想积累,因为在某些情况下它非常好,例如这个:
const double val = data | transform(...) | accumulate (...);
所以我想知道是否已将某些东西添加到 range-v3/C++20 范围,使我能够做到这一点。
没有
您唯一可以输入的是范围适配器——接受范围并产生范围的算法。采用范围和 return 单个对象(也称为变形)的算法在范围 v3 或 C++20 范围内 不可 管道化。
你必须这样写:
const double val = accumulate(data | transform(...));
至于为什么 accumulate
和类似的算法将努力成为 |
-able。考虑一下我们希望 algo(rng, x)
和 rng | algo(x)
表示相同的意思。此外,考虑 "total call" algo(rng, x)
可以完全约束(因为您拥有所有信息),而 "partial call" 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
来完成这项工作?
我发现 3 年前的旧问题说一般来说这是不可能的,但我真的很想积累,因为在某些情况下它非常好,例如这个:
const double val = data | transform(...) | accumulate (...);
所以我想知道是否已将某些东西添加到 range-v3/C++20 范围,使我能够做到这一点。
没有
您唯一可以输入的是范围适配器——接受范围并产生范围的算法。采用范围和 return 单个对象(也称为变形)的算法在范围 v3 或 C++20 范围内 不可 管道化。
你必须这样写:
const double val = accumulate(data | transform(...));
至于为什么 accumulate
和类似的算法将努力成为 |
-able。考虑一下我们希望 algo(rng, x)
和 rng | algo(x)
表示相同的意思。此外,考虑 "total call" algo(rng, x)
可以完全约束(因为您拥有所有信息),而 "partial call" 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
来完成这项工作?