当前位置: 首页 > 知识库问答 >
问题:

理解std::累积

太叔睿
2023-03-14

我想知道为什么需要std::acculture(又名reduce)第3个参数。对于那些不知道accumple是什么的人,它的用法如下:

vector<int> V{1,2,3};  
int sum = accumulate(V.begin(), V.end(), 0);
// sum == 6

调用acculture等同于:

sum = 0;  // 0 - value of 3rd param
for (auto x : V)  sum += x;

还有可选第4个参数,它允许用任何其他操作替换加法。

我听说的一个基本原理是,如果你不需要加起来,而是乘一个向量的元素,我们需要其他的(非零)初始值:

vector<int> V{1,2,3};
int product = accumulate(V.begin(), V.end(), 1, multiplies<int>());

但是为什么不像Python那样-为v.begin()设置初始值,并使用从v.begin()+1开始的范围。类似这样的事情:

int sum = accumulate(V.begin()+1, V.end(), V.begin());

这对任何行动都管用。为什么需要第三个参数?

共有1个答案

宿建本
2023-03-14

从目前的情况来看,如果代码确定一个范围不是空的,并且希望从范围的第一个元素开始进行累加,那么这是很烦人的。根据用于累加的操作,使用的“零”值并不总是很明显。

另一方面,如果您只提供了一个需要非空范围的版本,那么对于不确定其范围是否为空的调用者来说,这是非常恼人的。给他们增加了额外负担。

一种观点是,这两个世界的最佳之处当然是同时提供这两种功能。例如,Haskell提供了foldl1foldr1(需要非空列表)以及foldlfoldr(镜像std::transform)。

另一个观点是,由于一个可以通过简单的转换(如您所演示的:std::transform(Std::next(b),e,*b,f)--std::next是C++11,但这一点仍然成立)来实现另一个,因此最好使接口尽可能地最小,并且不损失真正的表达能力。

 类似资料:
  • 我试图理解这段代码,但我不明白为什么这个版本 比这快 在C++20之后它变成了 我只是想知道,使用std::move是否有任何真正的改进。 编辑2

  • 首先通过了解它们(指std::move和std::forward)不做什么来认识std::move和std::forward是非常有用的。std::move不move任何东西。std::forward也不转发任何东西。在运行时,他们什么都不做。不产生可执行代码,一个比特/Users/shikunfeng/Documents/neteaseWork/timeline_15_05_18/src/mai

  • 在我的项目中,我已经达到了一个点,需要在资源上的线程之间进行通信,这些资源很可能被写入,所以同步是必须的。然而,除了基本级别,我真的不理解同步。 考虑这个链接中的最后一个例子:http://www.bogotobogo.com/cplusplus/C11/7_C11_Thread_Sharing_Memory.php 该示例演示了三个线程(两个编写器和一个读取器)如何访问公共资源(列表)。 使用两

  • 本文向大家介绍理解C++编程中的std::function函数封装,包括了理解C++编程中的std::function函数封装的使用技巧和注意事项,需要的朋友参考一下 先来看看下面这两行代码: 这两行代码是从Cocos2d-x中摘出来的,重点是这两行代码的定义啊。std::function这是什么东西?如果你对上述两行代码表示毫无压力,那就不妨再看看本文,就当温故而知新吧。 std::functi

  • 在设计回调函数的时候,无可避免地会接触到可回调对象。在C++11中,提供了std::function和std::bind两个方法来对可回调对象进行统一和封装。 可调用对象 C++中有如下几种可调用对象:函数、函数指针、lambda表达式、bind对象、函数对象。其中,lambda表达式和bind对象是C++11标准中提出的(bind机制并不是新标准中首次提出,而是对旧版本中bind1st和bind

  • 显然,SWIG不理解并破坏Python绑定。例如,这适用于C: 但是这会破坏代码(除了为了简单起见有不同的行为,但这不是重点): (普通)未绑定函数的情况相同。那么,有人知道解决这个问题的方法吗?