std::accumulate
| Definiert in Header <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 Wertes init und der Elemente im Bereich [first, last).
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 [first, last) in der Reihenfolge.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 [first, last) in der Reihenfolge.Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
Tist nicht CopyConstructible.Tist nicht CopyAssignable.opmodifiziert ein beliebiges Element von[first,last).opmacht einen Iterator oder Teilbereich in[first,last]ungültig.
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der zu akkumulierenden Elemente definiert |
| init | - | Anfangswert der Akkumulation |
| op | - | binäres Operationsfunktionsobjekt, das angewendet wird. Die Signatur der Funktion sollte der folgenden entsprechen:
Die Signatur muss kein |
| Typanforderungen | ||
-InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
| ||
Rückgabewert
acc nach allen Modifikationen.
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;
}
|
Anmerkungen
std::accumulate führt eine linke Faltung durch. Um eine rechte Faltung durchzuführen, muss man die Reihenfolge der Argumente des binären Operators umkehren und reverse Iteratoren verwenden.
Wenn man es der Typinferenz überlässt, arbeitet op mit Werten des gleichen Typs wie init, was zu einer unerwünschten Umwandlung der Iteratorelemente führen kann. Zum Beispiel liefert std::accumulate(v.begin(), v.end(), 0) wahrscheinlich nicht das gewünschte Ergebnis, wenn v vom Typ std::vector<double> ist.
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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewandt auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 242 | C++98 | op konnte keine Nebenwirkungen haben
|
es darf die beteiligten Bereiche nicht modifizieren |
Siehe auch
| berechnet die Differenzen zwischen benachbarten Elementen in einem Bereich (Funktionsschablone) | |
| berechnet das innere Produkt zweier Elementbereiche (Funktionsschablone) | |
| berechnet die partielle Summe eines Elementbereichs (Funktionsschablone) | |
(C++17) |
ähnlich wie std::accumulate, jedoch ohne feste Reihenfolge (Funktionsschablone) |
(C++23) |
faltet einen Elementbereich links (Algorithmusfunktionsobjekt) |