Namespaces
Variants

std::accumulate

ja.cppreference.net より
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとレンジに関するアルゴリズム (C++20)
制約付きアルゴリズム、例えば ranges::copy, ranges::sort, ...
ソートと関連操作
分割操作
(C++11)    

ソート操作
二分探索操作
(分割済み範囲に対して)
集合操作 (ソート済み範囲に対して)
マージ操作 (ソート済み範囲に対して)
ヒープ操作
最小値/最大値操作
(C++11)
(C++17)
辞書比較操作
順列操作


 
 
ヘッダ <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) アキュムレータ acc (型 T) を初期値 init で初期化し、範囲 acc = acc + *i(C++20 まで)acc = std::move(acc) + *i(C++20 から) 内の各イテレータ i に対して順に [first, last) で変更します。
2) アキュムレータ acc (型 T) を初期値 init で初期化し、範囲 acc = op(acc, *i)(C++20 まで)acc = op(std::move(acc), *i)(C++20 から) 内の各イテレータ i に対して順に [first, last) で変更します。

以下のいずれかの条件が満たされる場合、動作は未定義です。

  • T が CopyConstructible ではない。
  • T が CopyAssignable ではない。
  • 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 すべての変更後の

。

実装例
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 (1)
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;
}

accumulate (2)

std::accumulate注釈 は左 畳み込み

を行います。右畳み込みを行うには、二項演算子の引数の順序を逆にし、逆方向イテレータを使用する必要があります。 op型推論に任せた場合、init は std::accumulate(v.begin(), v.end(), 0) と同じ型の値に対して操作するため、イテレータの要素が意図しないキャストになる可能性があります。例えば、v の型が std::vector<double> の場合、

は望ましい結果を与えない可能性があります。

#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]), // start with first element
                                    dash_fold);
    
    // Right fold using reverse iterators
    std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
                                     std::to_string(v.back()), // start with last element
                                     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++ 標準に遡って適用されました。

DR 適用先 公開時の動作 正しい動作
LWG 242 C++98 op は副作用を持つことができなかった 関係する範囲を変更してはならない

関連項目

範囲内の隣接する要素間の差を計算する
(関数テンプレート)
2つの範囲の要素の内積を計算する
(関数テンプレート)
範囲内の要素の部分和を計算する
(関数テンプレート)
(C++17)
std::accumulate と同様だが、順序不同で実行する
(関数テンプレート)
範囲の要素を左畳み込みする
(アルゴリズム関数オブジェクト)