Namespaces
Variants

std:: accumulate

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
定义于头文件 <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 ) 内元素的总和。

1) 使用初始值 init 初始化累加器 acc (类型为 T ),随后按顺序对范围 [ first , last ) 内的每个迭代器 i 通过 acc = acc + * i (C++20 前) acc = std :: move ( acc ) + * i (C++20 起) 进行修改。
2) 使用初始值 init 初始化累加器 acc (类型为 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 &
类型 Type1 必须满足: T 类型对象可隐式转换为 Type1 。类型 Type2 必须满足: InputIt 类型对象可解引用后隐式转换为 Type2 。类型 Ret 必须满足: T 类型对象可被赋予 Ret 类型的值。 ​

类型要求
-
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 ,但无序执行
(函数模板)
对元素范围进行左折叠
(算法函数对象)