Namensräume
Varianten
Aktionen

std::accumulate

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
accumulate
(C++17)
Operationen auf uninitialisiertem Speicher
 
 
Definiert in der Header-Datei <numeric>
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
(1) (constexpr seit C++20)
template< class InputIt, class T, class BinaryOp >
T accumulate( InputIt first, InputIt last, T init, BinaryOp op );
(2) (constexpr seit C++20)

Berechnet die Summe des gegebenen Werts init und der Elemente im Bereich [firstlast).

1) Initialisiert den Akkumulator acc (vom Typ T) mit dem Anfangswert init und modifiziert ihn dann mit acc = acc + *i(bis C++20)acc = std::move(acc) + *i(seit C++20) für jeden Iterator i im Bereich [firstlast) in Reihenfolge.
2) Initialisiert den Akkumulator acc (vom Typ T) mit dem Anfangswert init und modifiziert ihn dann mit acc = op(acc, *i)(bis C++20)acc = op(std::move(acc), *i)(seit C++20) für jeden Iterator i im Bereich [firstlast) in Reihenfolge.

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert

  • T ist nicht CopyConstructible.
  • T ist nicht CopyAssignable.
  • op modifiziert kein Element von [firstlast).
  • op macht keinen Iterator oder Teilbereich in [firstlast] ungültig.

Inhalt

[edit] Parameter

first, last - das Iteratorenpaar, das den Bereich der zu akkumulierenden Elemente definiert
init - Anfangswert des Akkumulators
op - ein binäres Operations-Funktionsobjekt, das angewendet wird.

Die Signatur der Funktion sollte äquivalent zu folgender sein:

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

Die Signatur muss nicht const & haben.
Der Typ  Type1 muss so beschaffen sein, dass ein Objekt des Typs T implizit in  Type1 konvertiert werden kann. Der Typ  Type2 muss so beschaffen sein, dass ein Objekt des Typs InputIt dereferenziert und dann implizit in  Type2 konvertiert werden kann. Der Typ Ret muss so beschaffen sein, dass einem Objekt des Typs T ein Wert des Typs Ret zugewiesen werden kann. ​

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

[edit] Rückgabewert

acc nach allen Modifikationen.

[edit] Mögliche Implementierung

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;
}

[edit] Hinweise

std::accumulate führt einen linken Fold durch. Um einen rechten Fold durchzuführen, muss die Reihenfolge der Argumente für den binären Operator umgekehrt und Reverse-Iteratoren verwendet werden.

Wenn op der Typinferenz überlassen wird, operiert er auf Werten vom gleichen Typ wie init, was zu unerwünschten Konvertierungen der Iteratorelemente führen kann. Zum Beispiel gibt std::accumulate(v.begin(), v.end(), 0) wahrscheinlich nicht das gewünschte Ergebnis, wenn v vom Typ std::vector<double> ist.

[edit] Beispiel

#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';
}

Ausgabe

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

[edit] Fehlerberichte

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

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 242 C++98 op darf keine Nebenwirkungen haben kann die beteiligten Bereiche nicht modifizieren

[edit] Siehe auch

berechnet die Differenzen zwischen benachbarten Elementen in einer Reihe
(Funktionstemplate) [bearbeiten]
berechnet das innere Produkt von zwei Elementreihen
(Funktionstemplate) [bearbeiten]
berechnet die partielle Summe einer Elementreihe
(Funktionstemplate) [bearbeiten]
(C++17)
ähnlich zu std::accumulate, außer Reihenfolge
(Funktionstemplate) [bearbeiten]
Faltet einen Elementbereich von links
(Algorithmus-Funktionsobjekt)[edit]