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
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 de map/reduce ordonnée sur la plage [ first1 , last1 ) 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 puis le modifie avec l'expression acc = acc + ( * i1 ) * ( * i2 ) (jusqu'en 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 native de + et *, cela calcule le produit scalaire des deux plages.
2) Initialise l'accumulateur acc (de type T ) avec la valeur initiale init puis le modifie avec l'expression acc = op1 ( acc, op2 ( * i1, * i2 ) ) (jusqu'en 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 .

Soit last2 comme le std:: distance ( first1, last1 ) ième itérateur suivant 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 un élément quelconque de [ first1 , last1 ) ou de [ first2 , last2 ) .
  • op1 ou op2 invalide un itérateur ou un sous-intervalle dans [ first1 , last1 ] ou dans [ first2 , last2 ] .

Table des matières

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 de "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 à :

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 les objets de types T et Type3 puissent être implicitement convertis en Type1 et Type2 respectivement. Le type Ret doit être tel qu'un objet de type T puisse se voir assigner une valeur de type Ret . ​

op2 - objet fonction d'opération binaire qui sera appliqué. Cette fonction de "produit" prend une valeur de chaque plage et produit une nouvelle valeur.

La signature de la fonction doit être équivalente à :

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 les objets de types InputIt1 et InputIt2 puissent ê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 puisse se voir assigner une valeur de type Ret . ​

Exigences de type
-
InputIt1, InputIt2 doivent 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 // depuis C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
    while (first1 != last1)
    {
        init = std::move(init) + (*first1) * (*first2); // std::move depuis C++20
        ++first1;
        ++first2;
    }
    return init;
}
inner_product (2)
template<class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2>
constexpr // depuis 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 depuis C++20
        ++first1;
        ++first2;
    }
    return init;
}

Notes

La version parallélisable de cet algorithme, std::transform_reduce , requiert que op1 et op2 soient commutatifs et associatifs, mais std::inner_product n'impose aucune exigence de ce type et exécute toujours les opérations dans l'ordre spécifié.

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 << "Produit scalaire de a et b : " << r1 << '\n';
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Nombre de correspondances par paires entre a et 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 modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applied to Behavior as published Correct behavior
LWG 242 C++98 op1 et op2 ne pouvaient pas avoir d'effets secondaires ils ne peuvent pas modifier les plages impliquées

Voir aussi

applique un objet appelable, puis réduit de manière non ordonnée
(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)