std::inner_product
| Definiert in der Header-Datei <numeric> |
||
template< class InputIt1, class InputIt2, class T > T inner_product( InputIt1 first1, InputIt1 last1, |
(1) | (constexpr seit C++20) |
template< class InputIt1, class InputIt2, class T, class BinaryOp1, class BinaryOp2 > |
(2) | (constexpr seit C++20) |
Berechnet das Skalarprodukt (d.h. die Summe der Produkte) oder führt eine geordnete Map/Reduce-Operation für den Bereich [first1, last1) und den Bereich von std::distance(first1, last1) Elementen beginnend bei first2.
T) mit dem Anfangswert init und modifiziert ihn dann mit dem Ausdruck acc = acc + (*i1) * (*i2)(until C++20)acc = std::move(acc) + (*i1) * (*i2)(since C++20) für jeden Iterator i1 im Bereich [first1, last1) in Ordnung und seinen entsprechenden Iterator i2 im Bereich beginnend bei first2. Für die eingebaute Bedeutung von + und *, berechnet dies das Skalarprodukt der beiden Bereiche.T) mit dem Anfangswert init und modifiziert ihn dann mit dem Ausdruck acc = op1(acc, op2(*i1, *i2))(until C++20)acc = op1(std::move(acc), op2(*i1, *i2))(since C++20) für jeden Iterator i1 im Bereich [first1, last1) in Ordnung und seinen entsprechenden Iterator i2 im Bereich beginnend bei first2.Gegeben last2 als den std::distance(first1, last1)ten nächsten Iterator von first2, ist das Verhalten undefiniert, wenn eine der folgenden Bedingungen erfüllt ist
-
Tist nicht CopyConstructible. -
Tist nicht CopyAssignable. - op1 oder op2 modifizieren ein Element von
[first1,last1)oder[first2,last2). - op1 oder op2 machen einen Iterator oder Teilbereich in
[first1,last1]oder[first2,last2]ungültig.
Inhalt |
[edit] Parameter
| first1, last1 | - | das Iteratorenpaar, das den Bereich von Elementen definiert, die |
| first2 | - | der Anfang des zweiten Bereichs von Elementen |
| init | - | Anfangswert der Summe der Produkte |
| op1 | - | binäres Operationsfunktions-Objekt, das angewendet wird. Diese "Summen"-Funktion nimmt einen Rückgabewert von op2 und den aktuellen Wert des Akkumulators entgegen und erzeugt einen neuen Wert, der im Akkumulator gespeichert wird. Die Signatur der Funktion sollte äquivalent zu folgender sein: Ret fun(const Type1 &a, const Type2 &b); Die Signatur muss nicht const & haben. |
| op2 | - | binäres Operationsfunktions-Objekt, das angewendet wird. Diese "Produkt"-Funktion nimmt einen Wert aus jedem Bereich und erzeugt einen neuen Wert. Die Signatur der Funktion sollte äquivalent zu folgender sein: Ret fun(const Type1 &a, const Type2 &b); Die Signatur muss nicht const & haben. |
| Typanforderungen | ||
-InputIt1, InputIt2 müssen die Anforderungen an LegacyInputIterator erfüllen. | ||
[edit] Rückgabewert
acc nach allen Modifikationen.
[edit] Mögliche Implementierung
| inner_product (1) |
|---|
template<class InputIt1, class InputIt2, class T> constexpr // since C++20 T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init) { while (first1 != last1) { init = std::move(init) + (*first1) * (*first2); // std::move since C++20 ++first1; ++first2; } return init; } |
| inner_product (2) |
template<class InputIt1, class InputIt2, class T, class BinaryOp1, class BinaryOp2> constexpr // since C++20 T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init, BinaryOp1 op1, BinaryOp2 op2) { while (first1 != last1) { init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++20 ++first1; ++first2; } return init; } |
[edit] Anmerkungen
Die parallelisierbare Version dieses Algorithmus, std::transform_reduce, erfordert, dass op1 und op2 kommutativ und assoziativ sind, aber std::inner_product stellt keine solchen Anforderungen und führt die Operationen immer in der angegebenen Reihenfolge aus.
[edit] Beispiel
#include <functional> #include <iostream> #include <numeric> #include <vector> int main() { std::vector<int> a{0, 1, 2, 3, 4}; std::vector<int> b{5, 4, 2, 3, 1}; int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0); std::cout << "Inner product of a and b: " << r1 << '\n'; int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0, std::plus<>(), std::equal_to<>()); std::cout << "Number of pairwise matches between a and b: " << r2 << '\n'; }
Ausgabe
Inner product of a and b: 21 Number of pairwise matches between a and b: 2
[edit] Fehlermeldungen
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 | op1 und op2 könnten keine Nebeneffekte haben | sie können die beteiligten Bereiche nicht modifizieren |
[edit] Siehe auch
| (C++17) |
wendet eine aufrufbare Funktion an und reduziert dann nicht-sequenziell (Funktionstemplate) |
| summiert oder faltet eine Reihe von Elementen (Funktionstemplate) | |
| berechnet die partielle Summe einer Elementreihe (Funktionstemplate) |