Namespaces
Variants

std:: partial_sum

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 OutputIt >

OutputIt partial_sum ( InputIt first, InputIt last,

OutputIt d_first ) ;
(1) (constexpr since C++20)
template < class InputIt, class OutputIt, class BinaryOp >

OutputIt partial_sum ( InputIt first, InputIt last,

OutputIt d_first, BinaryOp op ) ;
(2) (constexpr since C++20)
1) もし [ first , last ) が空の場合、何も行わない。
それ以外の場合、以下の操作を順番に実行します:
  1. アキュムレータ acc を作成します。その型は value type であり、 InputIt の値型で初期化され、 * first で初期化されます。
  2. acc * d_first に代入します。
  3. 各整数 i に対して、 [ 1 , std:: distance ( first, last ) ) の範囲で、以下の操作を順番に実行します:
a) acc + * iter (C++20以前) std :: move ( acc ) + * iter (C++20以降) を計算します。ここで iter first の次の i 番目の イテレータです。
b) 結果を acc に代入します。
c) acc [1] * dest に代入する。ここで dest d_first の次の i 番目の イテレータである。
2) (1) と同じですが、 op ( acc, * iter ) (C++20まで) op ( std :: move ( acc ) , * iter ) (C++20以降) の代わりに計算します。

実際の二項演算として binary_op が与えられた場合:

  • 以下のいずれかの条件が満たされる場合、プログラムは不適格となります:
  • InputIt の値型が * first から構築可能でない。
  • acc 書き込み可能 d_first に書き込めない。
  • binary_op ( acc, * iter ) (C++20以前) binary_op ( std :: move ( acc ) , * iter ) (C++20以降) の結果が InputIt の値型に暗黙変換できない。
  • d_last が返されるイテレータとして与えられた場合、以下のいずれかの条件が満たされると、動作は未定義となります:
  • binary_op [ first , last ) または [ d_first , d_last ) の任意の要素を変更する可能性があります。
  • binary_op [ first , last ] または [ d_first , d_last ] 内の任意のイテレータまたは部分範囲を無効化する可能性があります。


  1. 実際に代入される値は、前のステップでの代入結果です。ここでは代入結果が acc であると仮定します。

目次

翻訳のポイント: - 「Contents」を「目次」に翻訳 - HTMLタグ、属性、リンク先は一切変更せず保持 - C++関連の専門用語(Parameters、Return value、Complexityなど)は原文のまま保持 - 数値、クラス名、IDなどはそのまま維持 - フォーマットと構造は完全に保持

パラメータ

first, last - 合計する要素の範囲を定義するイテレータのペア
d_first - 宛先範囲の先頭。 first と等しくてもよい
op - 適用される二項演算関数オブジェクト。

関数のシグネチャは以下と同等であるべきです:

Ret fun ( const Type1 & a, const Type2 & b ) ;

シグネチャは const & を持つ必要はありません。
Type1 は、 std:: iterator_traits < InputIt > :: value_type のオブジェクトが Type1 に暗黙的に変換可能でなければなりません。型 Type2 は、 InputIt のオブジェクトが間接参照され、その後 Type2 に暗黙的に変換可能でなければなりません。型 Ret は、 InputIt のオブジェクトが間接参照され、型 Ret の値を代入可能でなければなりません。 ​

型要件
-
InputIt LegacyInputIterator の要件を満たさなければなりません。
-
OutputIt LegacyOutputIterator の要件を満たさなければなりません。

戻り値

書き込まれた最後の要素の次の要素を指すイテレータ、または d_first が返される( [ first , last ) が空の場合)。

計算量

与えられた N std:: distance ( first, last ) として:

1) 正確に N-1 回の operator + の適用。
2) 厳密に N-1 回の二項関数 op の適用。

実装例

partial_sum (1)
template<class InputIt, class OutputIt>
constexpr // since C++20
OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first)
{
    if (first == last)
        return d_first;
    typename std::iterator_traits<InputIt>::value_type sum = *first;
    *d_first = sum;
    while (++first != last)
    {
        sum = std::move(sum) + *first; // std::move since C++20
        *++d_first = sum;
    }
    return ++d_first;
    // or, since C++14:
    // return std::partial_sum(first, last, d_first, std::plus<>());
}
partial_sum (2)
template<class InputIt, class OutputIt, class BinaryOp>
constexpr // since C++20
OutputIt partial_sum(InputIt first, InputIt last, 
                     OutputIt d_first, BinaryOp op)
{
    if (first == last)
        return d_first;
    typename std::iterator_traits<InputIt>::value_type acc = *first;
    *d_first = acc;
    while (++first != last)
    {
        acc = op(std::move(acc), *first); // std::move since C++20
        *++d_first = acc;
    }
    return ++d_first;
}

注記

acc は、 LWG issue 539 の解決により導入されました。 acc を使用する理由(すなわち、直接結果を合計する * ( d_first + 2 ) = ( * first + * ( first + 1 ) ) + * ( first + 2 ) ; の代わりに)は、以下の型が一致しない場合に後者の意味が曖昧になるためです:

  • InputIt の値型
  • OutputIt の書き込み可能な型
  • operator + または op のパラメータの型
  • operator + または op の戻り値の型

acc は、計算の各ステップで値を保存および提供する中間オブジェクトとして機能します:

  • その型は InputIt の値型である
  • それは d_first に書き込まれる
  • その値は operator + または op に渡される
  • それは operator + または op の戻り値を格納する
enum not_int { x = 1, y = 2 };
char i_array[4] = {100, 100, 100, 100};
not_int e_array[4] = {x, x, y, y};
int  o_array[4];
// OK: operator+(char, char)を使用し、char値をint配列に代入
std::partial_sum(i_array, i_array + 4, o_array);
// エラー: not_int値をint配列に代入できません
std::partial_sum(e_array, e_array + 4, o_array);
// OK: 必要時に変換を実行
// 1. 型char(値型)の「acc」を作成
// 2. char引数はlong乗算に使用(char -> long)
// 3. longの積が「acc」に代入(long -> char)
// 4. 「acc」が「o_array」の要素に代入(char -> int)
// 5. 入力範囲の残りの要素を処理するためステップ2に戻る
std::partial_sum(i_array, i_array + 4, o_array, std::multiplies<long>{});

#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
    std::vector<int> v(10, 2); // v = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
    std::cout << "最初の " << v.size() << " 個の偶数: ";
    // 結果をcoutストリームに出力
    std::partial_sum(v.cbegin(), v.cend(), 
                     std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    // 結果をベクトルvに書き戻す
    std::partial_sum(v.cbegin(), v.cend(),
                     v.begin(), std::multiplies<int>());
    std::cout << "最初の " << v.size() << " 個の2の累乗: ";
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
}

出力:

最初の 10 個の偶数: 2 4 6 8 10 12 14 16 18 20 
最初の 10 個の2の累乗: 2 4 8 16 32 64 128 256 512 1024

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 242 C++98 op 副作用を持つことができなかった 関連する範囲を変更できない
LWG 539 C++98 結果の評価と代入が有効となるための
型要件が欠落していた
追加された

関連項目

範囲内の隣接する要素間の差分を計算する
(関数テンプレート)
範囲の要素を合計または畳み込む
(関数テンプレート)
std::partial_sum と類似しており、 i 番目 の入力要素を i 番目 の合計に含める
(関数テンプレート)
std::partial_sum と類似しており、 i 番目 の入力要素を i 番目 の合計から除外する
(関数テンプレート)