std:: partial_sum
|
Défini dans l'en-tête
<numeric>
|
||
|
template
<
class
InputIt,
class
OutputIt
>
OutputIt partial_sum
(
InputIt first, InputIt last,
|
(1) | (constexpr depuis C++20) |
|
template
<
class
InputIt,
class
OutputIt,
class
BinaryOp
>
OutputIt partial_sum
(
InputIt first, InputIt last,
|
(2) | (constexpr depuis C++20) |
[
first
,
last
)
est vide, ne fait rien.
-
Crée un accumulateur
acc
, dont le type est le
value type
de
InputIt, et l'initialise avec * first . - Assigne acc à * d_first .
-
Pour chaque entier
i
dans
[1,std:: distance ( first, last )), effectue les opérations suivantes dans l'ordre :
É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
InputItn'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.
-
Le type de valeur de
- É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].
-
binary_op
modifie tout élément de
- ↑ 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
&
.
|
| 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 ) :
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) |
|
|
(C++17)
|
similaire à
std::partial_sum
, inclut le
i
ème
élément d'entrée dans la
i
ème
somme
(modèle de fonction) |
|
(C++17)
|
similaire à
std::partial_sum
, exclut le
i
ème
élément d'entrée de la
i
ème
somme
(modèle de fonction) |