Namespaces
Variants

std:: partial_sum

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 InputIt, class OutputIt >

OutputIt partial_sum ( InputIt first, InputIt last,

OutputIt d_first ) ;
(1) (constexpr depuis C++20)
template < class InputIt, class OutputIt, class BinaryOp >

OutputIt partial_sum ( InputIt first, InputIt last,

OutputIt d_first, BinaryOp op ) ;
(2) (constexpr depuis C++20)
1) Si [ first , last ) est vide, ne fait rien.
Sinon, effectue les opérations suivantes dans l'ordre :
  1. Crée un accumulateur acc , dont le type est le value type de InputIt , et l'initialise avec * first .
  2. Assigne acc à * d_first .
  3. Pour chaque entier i dans [ 1 , std:: distance ( first, last ) ) , effectue les opérations suivantes dans l'ordre :
a) Calcule acc + * iter (jusqu'à C++20) std :: move ( acc ) + * iter (depuis C++20) , où iter est le prochain i ème itérateur de first .
b) Affecte le résultat à acc .
c) Affecte acc [1] à * dest , où dest est le prochain i ième itérateur de d_first .
2) Identique à (1) , mais calcule op ( acc, * iter ) (jusqu'à C++20) op ( std :: move ( acc ) , * iter ) (depuis C++20) à la place.

Étant donné binary_op comme l'opération binaire réelle :

  • Si l'une des conditions suivantes est satisfaite, le programme est mal formé :
  • Le type de valeur de InputIt n'est pas constructible à partir de * first .
  • acc n'est pas accessible en écriture vers d_first .
  • Le résultat de binary_op ( acc, * iter ) (jusqu'en C++20) binary_op ( std :: move ( acc ) , * iter ) (depuis C++20) n'est pas implicitement convertible vers le type de valeur de InputIt .
  • Étant donné d_last comme l'itérateur à retourner , si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
  • binary_op modifie tout élément de [ first , last ) ou [ d_first , d_last ) .
  • binary_op invalide tout itérateur ou sous-intervalle dans [ first , last ] ou [ d_first , d_last ] .


  1. La valeur réelle à assigner est le résultat de l'assignation à l'étape précédente. Nous supposons que le résultat de l'assignation est acc ici.

Table des matières

Paramètres

first, last - la paire d'itérateurs définissant l'intervalle des éléments à sommer
d_first - le début de l'intervalle de destination ; peut être égal à first
op - objet fonction d'opération binaire qui sera appliqué.

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 & .
Le type Type1 doit être tel qu'un objet de type std:: iterator_traits < InputIt > :: value_type puisse être implicitement converti en Type1 . Le type Type2 doit être tel qu'un objet de type InputIt puisse être déréférencé puis implicitement converti en Type2 . Le type Ret doit être tel qu'un objet de type InputIt puisse être déréférencé et assigné à une valeur de type Ret . ​

Exigences de type
-
InputIt doit satisfaire aux exigences de LegacyInputIterator .
-
OutputIt doit satisfaire aux exigences de LegacyOutputIterator .

Valeur de retour

Itérateur vers l'élément après le dernier élément écrit, ou d_first si [ first , last ) est vide.

Complexité

Étant donné N comme std:: distance ( first, last ) :

1) Exactement N-1 applications de l' operator + .
2) Exactement N-1 applications de la fonction binaire op .

Implémentation possible

partial_sum (1)
template<class InputIt, class OutputIt>
constexpr // depuis C++20
OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first)
{
    if (first == last)
        return d_first;
    typename std::iterator_traits<InputIt>::value_type sum = *first;
    *d_first = sum;
    while (++first != last)
    {
        sum = std::move(sum) + *first; // std::move depuis C++20
        *++d_first = sum;
    }
    return ++d_first;
    // ou, depuis C++14 :
    // return std::partial_sum(first, last, d_first, std::plus<>());
}
partial_sum (2)
template<class InputIt, class OutputIt, class BinaryOp>
constexpr // depuis C++20
OutputIt partial_sum(InputIt first, InputIt last, 
                     OutputIt d_first, BinaryOp op)
{
    if (first == last)
        return d_first;
    typename std::iterator_traits<InputIt>::value_type acc = *first;
    *d_first = acc;
    while (++first != last)
    {
        acc = op(std::move(acc), *first); // std::move depuis C++20
        *++d_first = acc;
    }
    return ++d_first;
}

Notes

acc a été introduit en raison de la résolution de LWG issue 539 . La raison d'utiliser acc plutôt que de sommer directement les résultats (c'est-à-dire * ( d_first + 2 ) = ( * first + * ( first + 1 ) ) + * ( first + 2 ) ; ) est que la sémantique de cette dernière est confuse si les types suivants ne correspondent pas :

  • le type de valeur de InputIt
  • le(s) type(s) accessible en écriture de OutputIt
  • les types des paramètres de operator + ou op
  • le type de retour de operator + ou op

acc sert d'objet intermédiaire pour stocker et fournir les valeurs à chaque étape du calcul :

  • son type est le type de valeur de InputIt
  • il est écrit dans d_first
  • sa valeur est passée à operator + ou op
  • il stocke la valeur de retour de operator + ou op
enum not_int { x = 1, y = 2 };
char i_array[4] = {100, 100, 100, 100};
not_int e_array[4] = {x, x, y, y};
int  o_array[4];
// OK : utilise operator+(char, char) et assigne des valeurs char au tableau int
std::partial_sum(i_array, i_array + 4, o_array);
// Erreur : impossible d'assigner des valeurs not_int au tableau int
std::partial_sum(e_array, e_array + 4, o_array);
// OK : effectue les conversions nécessaires
// 1. crée "acc" de type char (le type de valeur)
// 2. les arguments char sont utilisés pour la multiplication long (char -> long)
// 3. le produit long est assigné à "acc" (long -> char)
// 4. "acc" est assigné à un élément de "o_array" (char -> int)
// 5. retour à l'étape 2 pour traiter les éléments restants dans la plage d'entrée
std::partial_sum(i_array, i_array + 4, o_array, std::multiplies<long>{});

Exemple

#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
    std::vector<int> v(10, 2); // v = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
    std::cout << "Les premiers " << v.size() << " nombres pairs sont : ";
    // écrire le résultat vers le flux cout
    std::partial_sum(v.cbegin(), v.cend(), 
                     std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    // réécrire le résultat dans le vecteur v
    std::partial_sum(v.cbegin(), v.cend(),
                     v.begin(), std::multiplies<int>());
    std::cout << "Les premières " << v.size() << " puissances de 2 sont : ";
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
}

Sortie :

Les premiers 10 nombres pairs sont : 2 4 6 8 10 12 14 16 18 20 
Les premières 10 puissances de 2 sont : 2 4 8 16 32 64 128 256 512 1024

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 Appliqué à Comportement publié Comportement corrigé
LWG 242 C++98 op ne pouvait pas avoir d'effets secondaires il ne peut pas modifier les plages impliquées
LWG 539 C++98 les exigences de type nécessaires pour que les résultats
des évaluations et assignations soient valides manquaient
ajoutées

Voir aussi

calcule les différences entre les éléments adjacents dans une plage
(modèle de fonction)
additionne ou plie une plage d'éléments
(modèle de fonction)
similaire à std::partial_sum , inclut le i ème élément d'entrée dans la i ème somme
(modèle de fonction)
similaire à std::partial_sum , exclut le i ème élément d'entrée de la i ème somme
(modèle de fonction)