std::inner_product
| Definiert in Header <numeric>
|
||
template< class InputIt1, class InputIt2, class T >
T inner_product( InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init );
|
(1) | (constexpr seit C++20) |
template< class InputIt1, class InputIt2, class T,
class BinaryOp1, class BinaryOp2 >
T inner_product( InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init,
BinaryOp1 op1, BinaryOp2 op2 );
|
(2) | (constexpr seit C++20) |
Berechnet das innere Produkt (d. h. Summe der Produkte) oder führt eine geordnete Map/Reduce-Operation auf dem [first1, last1)-Bereich und dem Bereich der std::distance(first1, last1)-Elemente ab first2 durch.
acc (vom Typ T) mit dem Anfangswert init und modifiziert ihn dann mit dem Ausdruck acc = acc + (*i1) * (*i2)(bis C++20)acc = std::move(acc) + (*i1) * (*i2)(seit C++20) für jeden Iterator i1 im Bereich [first1, last1) in der Reihenfolge und seinen zugehörigen Iterator i2 im Bereich ab first2. Bei der eingebauten Bedeutung von + und * berechnet dies das innere Produkt der beiden Bereiche.acc (vom Typ T) mit dem Anfangswert init und modifiziert ihn dann mit dem Ausdruck acc = op1(acc, op2(*i1, *i2))(bis C++20)acc = op1(std::move(acc), op2(*i1, *i2))(seit C++20) für jeden Iterator i1 im Bereich [first1, last1) in der Reihenfolge und seinen zugehörigen Iterator i2 im Bereich ab first2.Gegeben last2 als der std::distance(first1, last1)-te nächste Iterator von first2. Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
Tist nicht CopyConstructible.Tist nicht CopyAssignable.op1oderop2modifiziert ein Element von[first1,last1)oder[first2,last2).op1oderop2macht einen Iterator oder Teilbereich in[first1,last1]oder[first2,last2]ungültig.
Parameter
| first1, last1 | - | das Iteratorpaar, das den Bereich der zu verarbeitenden Elemente definiert |
| first2 | - | der Anfang des zweiten Bereichs von Elementen |
| init | - | Anfangswert der Summe der Produkte |
| op1 | - | binäres Operationsfunktionsobjekt, das angewendet wird. Diese "Summen"-Funktion nimmt einen von op2 zurückgegebenen Wert und den aktuellen Wert des Akkumulators entgegen und erzeugt einen neuen Wert, der im Akkumulator gespeichert wird.Die Signatur der Funktion sollte der folgenden entsprechen:
Die Signatur muss kein |
| op2 | - | binäres Operationsfunktionsobjekt, das angewendet wird. Diese "Produkt"-Funktion nimmt einen Wert aus jedem Bereich entgegen und erzeugt einen neuen Wert. Die Signatur der Funktion sollte der folgenden entsprechen:
Die Signatur muss kein |
| Typanforderungen | ||
-InputIt1, InputIt2 muss die Anforderungen von LegacyInputIterator erfüllen.
| ||
Rückgabewert
acc nach allen Modifikationen.
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;
}
|
Hinweise
Die parallelisierbare Version dieses Algorithmus, std::transform_reduce, erfordert, dass op1 und op2 kommutativ und assoziativ sind, aber std::inner_product stellt keine solche Anforderung und führt die Operationen stets in der angegebenen Reihenfolge aus.
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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Richtiges Verhalten |
|---|---|---|---|
| LWG 242 | C++98 | op1 und op2 durften keine Nebenwirkungen haben
|
sie dürfen die beteiligten Bereiche nicht modifizieren |
Siehe auch
(C++17) |
wendet ein aufrufbares Objekt an und reduziert dann in beliebiger Reihenfolge (Funktionstemplate) |
| summiert oder faltet einen Bereich von Elementen (Funktionstemplate) | |
| berechnet die Partialsumme eines Bereichs von Elementen (Funktionstemplate) |