std:: accumulate
|
定义于头文件
<numeric>
|
||
|
template
<
class
InputIt,
class
T
>
T accumulate ( InputIt first, InputIt last, T init ) ; |
(1) | (自 C++20 起为 constexpr) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T accumulate ( InputIt first, InputIt last, T init, BinaryOp op ) ; |
(2) | (自 C++20 起为 constexpr) |
计算给定值
init
与范围
[
first
,
last
)
内元素的总和。
T
),随后按顺序对范围
[
first
,
last
)
内的每个迭代器
i
通过
acc
=
acc
+
*
i
(C++20 前)
acc
=
std
::
move
(
acc
)
+
*
i
(C++20 起)
进行修改。
T
),随后按顺序对范围
[
first
,
last
)
内的每个迭代器
i
通过
acc
=
op
(
acc,
*
i
)
(C++20 前)
acc
=
op
(
std
::
move
(
acc
)
,
*
i
)
(C++20 起)
修改累加器。
若满足以下任一条件,则行为未定义:
-
T不满足 可复制构造 要求。 -
T不满足 可复制赋值 要求。 -
op
修改了
[first,last)范围内的任何元素。 -
op
使
[first,last]范围内的任何迭代器或子区间失效。
目录 |
参数
| first, last | - | 定义待累加元素 范围 的迭代器对 |
| init | - | 累加的初始值 |
| op | - |
将被应用的二元操作函数对象
函数签名应等价于: Ret fun ( const Type1 & a, const Type2 & b ) ;
签名无需包含
const
&
。
|
| 类型要求 | ||
-
InputIt
必须满足
LegacyInputIterator
的要求。
|
||
返回值
acc 在所有修改之后。
可能的实现
| accumulate (1) |
|---|
template<class InputIt, class T> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init) { for (; first != last; ++first) init = std::move(init) + *first; // std::move since C++20 return init; } |
| accumulate (2) |
template<class InputIt, class T, class BinaryOperation> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init, BinaryOperation op) { for (; first != last; ++first) init = op(std::move(init), *first); // std::move since C++20 return init; } |
注释
std::accumulate
执行的是
左折叠
操作。若要执行右折叠,必须反转二元运算符的参数顺序,并使用反向迭代器。
如果留给类型推断处理, op 会以与 init 相同的类型进行操作,这可能导致迭代器元素发生非预期的类型转换。例如,当 v 的类型为 std:: vector < double > 时, std :: accumulate ( v. begin ( ) , v. end ( ) , 0 ) 很可能不会产生期望的结果。
示例
#include <functional> #include <iostream> #include <numeric> #include <string> #include <vector> int main() { std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int sum = std::accumulate(v.begin(), v.end(), 0); int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>()); auto dash_fold = [](std::string a, int b) { return std::move(a) + '-' + std::to_string(b); }; std::string s = std::accumulate(std::next(v.begin()), v.end(), std::to_string(v[0]), // 从第一个元素开始 dash_fold); // 使用反向迭代器进行右折叠 std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(), std::to_string(v.back()), // 从最后一个元素开始 dash_fold); std::cout << "sum: " << sum << '\n' << "product: " << product << '\n' << "dash-separated string: " << s << '\n' << "dash-separated string (right-folded): " << rs << '\n'; }
输出:
sum: 55 product: 3628800 dash-separated string: 1-2-3-4-5-6-7-8-9-10 dash-separated string (right-folded): 10-9-8-7-6-5-4-3-2-1
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 242 | C++98 | op 不能有副作用 | 它不能修改所涉及的区间 |
参见
|
计算范围内相邻元素的差值
(函数模板) |
|
|
计算两个元素范围的内积
(函数模板) |
|
|
计算元素范围的部分和
(函数模板) |
|
|
(C++17)
|
类似于
std::accumulate
,但无序执行
(函数模板) |
|
(C++23)
|
对元素范围进行左折叠
(算法函数对象) |