std::inner_product
| Défini dans l'en-tête <numeric>
|
||
template< class InputIt1, class InputIt2, class T >
T inner_product( InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init );
|
(1) | (constexpr depuis 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 depuis C++20) |
Calcule le produit scalaire (c'est-à-dire la somme des produits) ou effectue une opération map/reduce ordonnée sur la plage [first1, last1) et la plage de std::distance(first1, last1) éléments commençant à first2.
acc (de type T) avec la valeur initiale init et puis le modifie avec l'expression acc = acc + (*i1) * (*i2)(jusqu'à C++20)acc = std::move(acc) + (*i1) * (*i2)(depuis C++20) pour chaque itérateur i1 dans la plage [first1, last1) dans l'ordre et son itérateur correspondant i2 dans la plage commençant à first2. Pour la signification intégrée de + et *, cela calcule le produit scalaire des deux plages.acc (de type T) avec la valeur initiale init et puis le modifie avec l'expression acc = op1(acc, op2(*i1, *i2))(jusqu'à C++20)acc = op1(std::move(acc), op2(*i1, *i2))(depuis C++20) pour chaque itérateur i1 dans la plage [first1, last1) dans l'ordre et son itérateur correspondant i2 dans la plage commençant à first2.Étant donné last2 comme le std::distance(first1, last1)ième prochain itérateur de first2, si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
Tn'est pas CopyConstructible.Tn'est pas CopyAssignable.op1ouop2modifie tout élément de[first1,last1)ou[first2,last2).op1ouop2invalide tout itérateur ou sous-plage dans[first1,last1]ou[first2,last2].
Paramètres
| first1, last1 | - | la paire d'itérateurs définissant la plage d'éléments à |
| first2 | - | le début de la deuxième plage d'éléments |
| init | - | valeur initiale de la somme des produits |
| op1 | - | objet fonction d'opération binaire qui sera appliqué. Cette fonction \"somme\" prend une valeur retournée par op2 et la valeur actuelle de l'accumulateur et produit une nouvelle valeur à stocker dans l'accumulateur.La signature de la fonction doit être équivalente à ce qui suit :
La signature n'a pas besoin d'avoir |
| op2 | - | objet fonction d'opération binaire qui sera appliqué. Cette fonction \"produit\" prend une valeur de chaque plage et produit une nouvelle valeur. La signature de la fonction doit être équivalente à ce qui suit :
La signature n'a pas besoin d'avoir |
| Exigences de type | ||
-InputIt1, InputIt2 doit satisfaire aux exigences de LegacyInputIterator.
| ||
Valeur de retour
acc après toutes les modifications.
Implémentation possible
| 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;
}
|
Notes
La version parallélisable de cet algorithme, std::transform_reduce, nécessite op1 et op2 d'être commutatifs et associatifs, mais std::inner_product n'impose pas une telle exigence, et effectue toujours les opérations dans l'ordre donné.
Exemple
#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';
}
Sortie :
Inner product of a and b: 21
Number of pairwise matches between a and b: 2
Rapports de défauts
Les rapports de défauts suivants modifiant le comportement ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| LWG 242 | C++98 | op1 et op2 ne pouvaient pas avoir d'effets secondaires
|
ils ne peuvent pas modifier les plages concernées |
Voir aussi
(C++17) |
applique un invocable, puis réduit sans ordre (modèle de fonction) |
| additionne ou plie une plage d'éléments (modèle de fonction) | |
| calcule la somme partielle d'une plage d'éléments (modèle de fonction) |