简体   繁体   English

std::transform 可以替换为 std::accumulate 吗?

[英]Can std::transform be replaced by std::accumulate?

I have a general question.我有一个普遍的问题。 Can we always replace std::transform with std::accumulate ?我们可以总是用std::accumulate替换std::transform吗? I have seen this replacement in many cases/examples.我在许多情况/示例中都看到了这种替换。 So is this possible in theory, and if it is then why std::transform was introduced?那么这在理论上是否可行,如果是这样,那么为什么要引入std::transform呢?

Those two algorithms have completely different purpose.这两种算法的目的完全不同。

std::accumulate is known as fold in functional programming world, and it's purpose is iterate over elements of a sequence and apply two-argument folding operation to those elements, with one argument being result of previous fold and other being element of the sequence. std::accumulate在函数式编程世界中被称为折叠,它的目的是迭代序列的元素并对这些元素应用两个参数的折叠操作,一个参数是先前折叠的结果,另一个是序列的元素。 It naturally returns the a single result - a fold of all elements of a sequence into one value.它自然地返回单个结果 - 将序列的所有元素折叠成一个值。

On the other hand, std::transform copies values from one sequence to another, applying a unary operation to each element.另一方面, std::transform值从一个序列复制到另一个序列,对每个元素应用一元运算。 It returns an iterator to the end of sequence.它返回一个迭代器到序列的末尾。

The fact that you can supply any code as the fold operation allows us to use std::accumulate as a generic loop replacement, including an option to copy values into some other container, but that it is ill-advised, as the whole reason for introducing those (rather simple) algorithms was to make programs more explicit.您可以提供任何代码作为折叠操作的事实允许我们使用std::accumulate作为通用循环替换,包括将值复制到其他容器中的选项,但这是不明智的,因为它的全部原因引入这些(相当简单的)算法是为了使程序更加明确。 Making one algo to perform the task which is normally associated to another algo is less explicit and counter-intuitive.让一个算法执行通常与另一个算法相关联的任务是不那么明确和违反直觉的。

A generic loop replacement algo is std::for_each , but with range for loops it became largely obsolete and I have not seen it in use for a long time.一个通用的循环替换算法是std::for_each ,但是对于循环的范围,它在很大程度上已经过时了,我已经很长时间没有看到它在使用了。

Can we always replace std::transform with std::accumulate ?我们可以总是用std::accumulate替换std::transform吗?

No. Per cppreference std::accumulate 's binary predicate op has没有。每个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 . op不得使任何迭代器无效,包括结束迭代器,也不得修改所涉及范围的任何元素,以及*last

So it can't actually transform the range you give it which is a main use case for std::transform .所以它实际上不能转换你给它的范围,这是std::transform的主要用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM