std::transform可以换成std::accumulate吗?

Can std::transform be replaced by std::accumulate?

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

Can we always replace std::transform with std::accumulate?

没有。每个 cppreference std::accumulate 的二元谓词 op

op must not invalidate any iterators, including the end iterators, nor modify any elements of the range involved, and also *last.

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

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

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

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

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

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