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,但是对于循环的范围,它基本上已经过时了,我已经很长时间没有看到它被使用了。
我有一个一般性问题。我们总是可以用 std::accumulate
替换 std::transform
吗?我在许多 cases/examples 中看到过这种替换。那么这在理论上是否可能,如果是,那么为什么要引入 std::transform
?
Can we always replace
std::transform
withstd::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,但是对于循环的范围,它基本上已经过时了,我已经很长时间没有看到它被使用了。