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
Definiert im Header <numeric>
template < class InputIt, class OutputIt >

OutputIt partial_sum ( InputIt first, InputIt last,

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

OutputIt partial_sum ( InputIt first, InputIt last,

OutputIt d_first, BinaryOp op ) ;
(2) (constexpr seit C++20)
1) Falls [ first , last ) leer ist, tut nichts.
Andernfalls führt die folgenden Operationen in dieser Reihenfolge aus:
  1. Erstellt einen Akkumulator acc , dessen Typ der Werttyp von InputIt ist, und initialisiert ihn mit * first .
  2. Weist acc an * d_first zu.
  3. Für jede ganze Zahl i in [ 1 , std:: distance ( first, last ) ) , führt die folgenden Operationen in dieser Reihenfolge aus:
a) Berechnet acc + * iter (bis C++20) std :: move ( acc ) + * iter (seit C++20) , wobei iter der nächste i te Iterator von first ist.
b) Weist das Ergebnis acc zu.
c) Weist acc [1] an * dest zu, wobei dest der nächste i te Iterator von d_first ist.
2) Gleich wie (1) , berechnet jedoch op ( acc, * iter ) (bis C++20) op ( std :: move ( acc ) , * iter ) (seit C++20) stattdessen.

Gegeben binary_op als die tatsächliche binäre Operation:

  • Wenn eine der folgenden Bedingungen erfüllt ist, ist das Programm fehlerhaft:
  • Der Werttyp von InputIt ist nicht konstruierbar aus * first .
  • acc ist nicht schreibbar nach d_first .
  • Das Ergebnis von binary_op ( acc, * iter ) (bis C++20) binary_op ( std :: move ( acc ) , * iter ) (seit C++20) ist nicht implizit konvertierbar zum Werttyp von InputIt .
  • Gegeben sei d_last als der zurückzugebende Iterator. Falls eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
  • binary_op modifiziert beliebige Elemente von [ first , last ) oder [ d_first , d_last ) .
  • binary_op invalidiert beliebige Iteratoren oder Teilbereiche in [ first , last ] oder [ d_first , d_last ] .


  1. Der tatsächlich zuzuweisende Wert ist das Ergebnis der Zuweisung im vorherigen Schritt. Wir nehmen an, dass das Zuweisungsergebnis hier acc ist.

Inhaltsverzeichnis

Parameter

first, last - das Iteratorpaar, das den Bereich der zu summierenden Elemente definiert
d_first - der Anfang des Zielbereichs; kann gleich first sein
op - binäres Funktionsobjekt, das angewendet wird.

Die Signatur der Funktion sollte äquivalent zu Folgendem sein:

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

Die Signatur muss nicht const & enthalten.
Der Typ Type1 muss so beschaffen sein, dass ein Objekt vom Typ std:: iterator_traits < InputIt > :: value_type implizit in Type1 konvertiert werden kann. Der Typ Type2 muss so beschaffen sein, dass ein Objekt vom Typ InputIt dereferenziert und dann implizit in Type2 konvertiert werden kann. Der Typ Ret muss so beschaffen sein, dass ein Objekt vom Typ InputIt dereferenziert und ein Wert vom Typ Ret zugewiesen werden kann. ​

Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
OutputIt muss die Anforderungen von LegacyOutputIterator erfüllen.

Rückgabewert

Iterator auf das Element nach dem letzten geschriebenen Element, oder d_first falls [ first , last ) leer ist.

Komplexität

Gegeben N als std:: distance ( first, last ) :

1) Genau N-1 Anwendungen des operator + .
2) Genau N-1 Anwendungen der binären Funktion op .

Mögliche Implementierung

partial_sum (1)
template<class InputIt, class OutputIt>
constexpr // seit 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 seit C++20
        *++d_first = sum;
    }
    return ++d_first;
    // oder, seit C++14:
    // return std::partial_sum(first, last, d_first, std::plus<>());
}
partial_sum (2)
template<class InputIt, class OutputIt, class BinaryOp>
constexpr // seit 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 seit C++20
        *++d_first = acc;
    }
    return ++d_first;
}

Hinweise

acc wurde aufgrund der Lösung von LWG Issue 539 eingeführt. Der Grund für die Verwendung von acc anstatt der direkten Aufsummierung der Ergebnisse (d.h. * ( d_first + 2 ) = ( * first + * ( first + 1 ) ) + * ( first + 2 ) ; ) liegt darin, dass die Semantik des Letzteren verwirrend ist, wenn die folgenden Typen nicht übereinstimmen:

  • der Werttyp von InputIt
  • der schreibbare Typ (oder die schreibbaren Typen) von OutputIt
  • die Typen der Parameter von operator + oder op
  • der Rückgabetyp von operator + oder op

acc dient als Zwischenobjekt zum Speichern und Bereitstellen der Werte für jeden Schritt der Berechnung:

  • sein Typ ist der Werttyp von InputIt
  • es wird geschrieben nach d_first
  • sein Wert wird übergeben an operator + oder op
  • es speichert den Rückgabewert von operator + oder 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: verwendet operator+(char, char) und weist char-Werte dem int-Array zu
std::partial_sum(i_array, i_array + 4, o_array);
// Fehler: kann not_int-Werte nicht dem int-Array zuweisen
std::partial_sum(e_array, e_array + 4, o_array);
// OK: führt Konvertierungen bei Bedarf durch
// 1. erstellt "acc" vom Typ char (der Werttyp)
// 2. die char-Argumente werden für die long-Multiplikation verwendet (char -> long)
// 3. das long-Produkt wird "acc" zugewiesen (long -> char)
// 4. "acc" wird einem Element von "o_array" zugewiesen (char -> int)
// 5. zurück zu Schritt 2, um die verbleibenden Elemente im Eingabebereich zu verarbeiten
std::partial_sum(i_array, i_array + 4, o_array, std::multiplies<long>{});

Beispiel

#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 << "Die ersten " << v.size() << " geraden Zahlen sind: ";
    // Ergebnis in den cout-Stream schreiben
    std::partial_sum(v.cbegin(), v.cend(), 
                     std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    // Ergebnis zurück in den Vektor v schreiben
    std::partial_sum(v.cbegin(), v.cend(),
                     v.begin(), std::multiplies<int>());
    std::cout << "Die ersten " << v.size() << " Zweierpotenzen sind: ";
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
}

Ausgabe:

Die ersten 10 geraden Zahlen sind: 2 4 6 8 10 12 14 16 18 20 
Die ersten 10 Zweierpotenzen sind: 2 4 8 16 32 64 128 256 512 1024

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 242 C++98 op konnte keine Nebeneffekte haben es kann die beteiligten Bereiche nicht modifizieren
LWG 539 C++98 die Typanforderungen für gültige Ergebnisauswertungen
und Zuweisungen fehlten
hinzugefügt

Siehe auch

berechnet die Differenzen zwischen benachbarten Elementen in einem Bereich
(Funktions-Template)
summiert oder faltet eine Reihe von Elementen
(Funktions-Template)
ähnlich zu std::partial_sum , schließt das i te Eingabeelement in der i ten Summe ein
(Funktions-Template)
ähnlich zu std::partial_sum , schließt das i te Eingabeelement aus der i ten Summe aus
(Funktions-Template)