【问题标题】:Can I pipe to range-v3 accumulate?我可以管道到 range-v3 累积吗?
【发布时间】:2020-03-26 14:03:31
【问题描述】:

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

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

所以我想知道是否已将某些内容添加到 range-v3/C++20 范围以使我能够执行此操作。

【问题讨论】:

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


    【解决方案1】:

    没有。

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

    你必须这样写:

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

    至于为什么accumulate 和类似的算法很难成为|-able。考虑一下我们希望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——使得整个表达式格式不正确,因为没有@ 987654342@。

    您如何使用accumulate 完成这项工作?

    【讨论】:

    • 哎哟......这真的很难看......我认为他们有充分的理由,但我没有看到它(可能是一般情况下的一些问题,他们不想为累积做例外)。
    • @NoSenseEtAl 添加了一个解释为什么你不能使accumulate 成为管道。
    • 我假设在以后决定它想要做什么的地方对累积的惰性求值进行了考虑但被拒绝了,因为它会与 auto 一起工作(与表达式模板相同的问题,其中 Matrix m = something; 是不同的from auto m = something; 因为你需要手动触发转换?)
    猜你喜欢
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 2020-07-31
    • 2017-04-10
    • 2020-04-06
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多