【问题标题】:Can std::transform be replaced by std::accumulate?std::transform 可以替换为 std::accumulate 吗?
【发布时间】:2020-01-23 21:32:15
【问题描述】:

我有一个一般性问题。我们可以总是用std::accumulate 替换std::transform 吗?我在许多情况/示例中都看到了这种替换。那么这在理论上是否可行,如果是,那么为什么要引入std::transform

【问题讨论】:

  • 您可以用普通循环替换,也可以用条件句和 goto 替换普通循环。如果不是绝对必要的,为什么还要有循环?
  • @molbdnilo 是的,你说得对,但是假设我的问题的答案是肯定的(根据答案,这不是)。那我想找找std::transform 被引入的原因[让程序更明确,代码更容易阅读,让代码运行得更快,等等..]。

标签: c++ functional-programming stl std


【解决方案1】:

我们能否始终将std::transform 替换为std::accumulate

没有。每cppreferencestd::accumulate的二元谓词op

op 不得使任何迭代器无效,包括结束迭代器,也不得修改所涉及范围的任何元素,以及*last

所以它实际上不能转换你给它的范围,这是std::transform 的主要用例。

【讨论】:

  • 由于 OP 从未提及他们在重叠序列上使用 transform,因此我不确定答案是否适用。
  • @SergeyA 问题是我们可以总是用std::accumulate 替换std::transform 吗?这回答了这个问题。
  • 我同意这一点,但我认为最好澄清这部分。简单阅读您的答案(至少对我而言)表明,累积永远不能用于代替转换,这是不正确的。
  • @SergeyA 我有。我引用了 OP 的文字并给出了答案。不并不意味着你永远做不到。这只是意味着你不能总是这样做。
  • imho 最后一句话说得很清楚。 transform 可以做的比accumulate 更多,这并不意味着accumulate 永远不能取代transform
【解决方案2】:

这两种算法的目的完全不同。

std::accumulate 在函数式编程世界中被称为 fold,其目的是遍历序列的元素并对这些元素应用双参数折叠操作,其中一个参数是先前的结果fold 和其他是序列的元素。它自然地返回单个结果 - 将序列的所有元素 折叠 为一个值。

另一方面,std::transform 将值从一个序列复制到另一个序列,对每个元素应用一元运算。它返回一个指向序列末尾的迭代器。

您可以提供任何代码作为折叠操作的事实允许我们使用std::accumulate 作为通用循环替换,包括将值复制到其他容器的选项,但整体而言这是不明智的引入这些(相当简单的)算法的原因是为了让程序更加明确。让一个算法执行通常与另一个算法相关联的任务是不那么明确和违反直觉的。

一个通用的循环替换算法是std::for_each,但是对于循环的范围,它在很大程度上已经过时了,我已经很长时间没有看到它在使用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    相关资源
    最近更新 更多