Namespaces
Variants

std::inner_product

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, par ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Opérations de tri et connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations d'ensemble (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
 
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 [first1last1) et la plage de std::distance(first1, last1) éléments commençant à first2.

1) Initialise l'accumulateur 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 [first1last1) 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.
2) Initialise l'accumulateur 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 [first1last1) 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 :

  • T n'est pas CopyConstructible.
  • T n'est pas CopyAssignable.
  • op1 ou op2 modifie tout élément de [first1last1) ou [first2last2).
  • op1 ou op2 invalide tout itérateur ou sous-plage dans [first1last1] ou [first2last2].

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 :

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

La signature n'a pas besoin d'avoir const &.
Les types Type1 et Type2 doivent être tels que des objets de types T et Type3 peuvent être implicitement convertis en Type1 et Type2 respectivement. Le type Ret doit être tel qu'un objet de type T peut se voir attribuer une valeur de type Ret. ​

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 :

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

La signature n'a pas besoin d'avoir const &.
Les types Type1 et Type2 doivent être tels que des objets de types InputIt1 et InputIt2 peuvent être déréférencés puis implicitement convertis en Type1 et Type2 respectivement. Le type Ret doit être tel qu'un objet de type Type3 peut se voir attribuer une valeur de type Ret. ​

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

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)