Namespaces
Variants

std:: inner_product

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 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 Skalarprodukt (d.h. die Summe der Produkte) oder führt eine geordnete Map/Reduce-Operation auf dem Bereich [ first1 , last1 ) und dem Bereich von std:: distance ( first1, last1 ) Elementen beginnend bei first2 durch.

1) Initialisiert den Akkumulator 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 Reihenfolge und seinem entsprechenden Iterator i2 im Bereich beginnend bei first2 . Für die eingebaute Bedeutung von + und * berechnet dies das Skalarprodukt der beiden Bereiche.
2) Initialisiert den Akkumulator 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 Reihenfolge und seinen entsprechenden Iterator i2 im Bereich beginnend bei first2 .

Gegeben last2 als der std:: distance ( first1, last1 ) te nächste Iterator von first2 , falls eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:

  • T ist nicht CopyConstructible .
  • T ist nicht CopyAssignable .
  • op1 oder op2 modifiziert irgendein Element von [ first1 , last1 ) oder [ first2 , last2 ) .
  • op1 oder op2 invalidisiert irgendeinen Iterator oder Teilbereich in [ first1 , last1 ] oder [ first2 , last2 ] .

Inhaltsverzeichnis

Parameter

first1, last1 - das Iteratorpaar, das den Bereich der Elemente definiert
first2 - der Beginn des zweiten Elementbereichs
init - Anfangswert der Summe der Produkte
op1 - binäres Funktionsobjekt, das angewendet wird. Diese "Summen"-Funktion nimmt einen von op2 zurückgegebenen Wert und den aktuellen Wert des Akkumulators und erzeugt einen neuen Wert, der im Akkumulator gespeichert wird.

Die Signatur der Funktion sollte folgender entsprechen:

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

Die Signatur muss nicht const & enthalten.
Die Typen Type1 und Type2 müssen so beschaffen sein, dass Objekte der Typen T und Type3 implizit in Type1 bzw. Type2 konvertiert werden können. Der Typ Ret muss so beschaffen sein, dass einem Objekt vom Typ T ein Wert vom Typ Ret zugewiesen werden kann. ​

op2 - binäres Funktionsobjekt, das angewendet wird. Diese "Produkt"-Funktion nimmt einen Wert aus jedem Bereich und erzeugt einen neuen Wert.

Die Signatur der Funktion sollte folgender entsprechen:

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

Die Signatur muss nicht const & enthalten.
Die Typen Type1 und Type2 müssen so beschaffen sein, dass Objekte der Typen InputIt1 und InputIt2 dereferenziert und dann implizit in Type1 bzw. Type2 konvertiert werden können. Der Typ Ret muss so beschaffen sein, dass einem Objekt vom Typ Type3 ein Wert vom Typ Ret zugewiesen werden kann. ​

Typanforderungen
-
InputIt1, InputIt2 müssen die Anforderungen von LegacyInputIterator erfüllen.

Rückgabewert

acc nach allen Änderungen.

Mögliche Implementierung

inner_product (1)
template<class InputIt1, class InputIt2, class T>
constexpr // seit C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
    while (first1 != last1)
    {
        init = std::move(init) + (*first1) * (*first2); // std::move seit C++20
        ++first1;
        ++first2;
    }
    return init;
}
inner_product (2)
template<class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2>
constexpr // seit 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 seit 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 << "Inneres Produkt von a und b: " << r1 << '\n';
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Anzahl paarweiser Übereinstimmungen zwischen a und 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 Korrektes Verhalten
LWG 242 C++98 op1 und op2 konnten keine Nebeneffekte haben sie können die beteiligten Bereiche nicht modifizieren

Siehe auch

wendet einen Aufrufbaren an und reduziert dann außerhalb der Reihenfolge
(Funktions-Template)
summiert oder faltet eine Reihe von Elementen
(Funktions-Template)
berechnet die Teilsumme einer Reihe von Elementen
(Funktions-Template)