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) (constexpr since C++20)
template < class InputIt, class T, class BinaryOp >
T accumulate ( InputIt first, InputIt last, T init, BinaryOp op ) ;
(2) (constexpr since C++20)

指定された値 init と範囲 [ first , last ) 内の要素の合計を計算します。

1) アキュムレータ acc (型 T )を初期値 init で初期化し、その後範囲 [ first , last ) 内の各イテレータ i に対して順番に acc = acc + * i (C++20まで) acc = std :: move ( acc ) + * i (C++20以降) で変更します。
2) アキュムレータ acc (型 T )を初期値 init で初期化し、その後範囲 [ first , last ) 内の各イテレータ i に対して順番に acc = op ( acc, * i ) (C++20まで) acc = op ( std :: move ( acc ) , * i ) (C++20以降) で更新します。

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

  • 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 すべての変更後。

実装例

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 は左 fold を実行します。右foldを実行するには、二項演算子への引数の順序を逆にし、逆方向イテレータを使用する必要があります。

型推論に任せた場合、 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]), // 最初の要素から開始
                                    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++規格に対して遡及的に適用されました。

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

関連項目

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