Namespaces
Variants

std::ranges::transform, std::ranges::unary_transform_result, std::ranges::binary_transform_result

Depuis fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur les plages (C++20)
Algorithmes contraints, par exemple 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 apparentées
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur des plages partitionnées)
Opérations d'ensemble (sur des plages triées)
Opérations de fusion (sur des 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


 
Algorithmes contraints
Tous les noms de ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modificatrices
Opérations de séquence modificatrices
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur des plages triées)
       
       
Opérations d'ensemble (sur des plages triées)
Opérations de tas
Opérations de minimum/maximum
       
       
Opérations de permutation
Opérations de pliage
Opérations sur le stockage non initialisé
Types de retour
 
Défini dans l'en-tête <algorithm>
Signature d'appel
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
          std::copy_constructible F, class Proj = std::identity >
requires std::indirectly_writable<O,
                                  std::indirect_result_t<F&, std::projected<I, Proj>>>
constexpr unary_transform_result<I, O>
    transform( I first1, S last1, O result, F op, Proj proj = {} );
(1) (depuis C++20)
template< ranges::input_range R, std::weakly_incrementable O,
          std::copy_constructible F, class Proj = std::identity >
requires std::indirectly_writable<O,
             std::indirect_result_t<F&, std::projected<ranges::iterator_t<R>, Proj>>>
constexpr unary_transform_result<ranges::borrowed_iterator_t<R>, O>
    transform( R&& r, O result, F op, Proj proj = {} );
(2) (depuis C++20)
template< std::input_iterator I1, std::sentinel_for<I1> S1,
          std::input_iterator I2, std::sentinel_for<I2> S2,
          std::weakly_incrementable O,
          std::copy_constructible F,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::indirectly_writable<O,
             std::indirect_result_t<F&,
                                    std::projected<I1, Proj1>,
                                    std::projected<I2, Proj2>>>
constexpr binary_transform_result<I1, I2, O>
    transform( I1 first1, S1 last1, I2 first2, S2 last2, O result,
               F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {} );
(3) (depuis C++20)
template< ranges::input_range R1,
          ranges::input_range R2,
          std::weakly_incrementable O,
          std::copy_constructible F,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::indirectly_writable<O,
             std::indirect_result_t<F&,
                 std::projected<ranges::iterator_t<R1>, Proj1>,
                 std::projected<ranges::iterator_t<R2>, Proj2>>>
constexpr binary_transform_result<ranges::borrowed_iterator_t<R1>,
                                  ranges::borrowed_iterator_t<R2>, O>
    transform( R1&& r1, R2&& r2, O result, F binary_op,
               Proj1 proj1 = {}, Proj2 proj2 = {} );
(4) (depuis C++20)
Types d'assistance
template< class I, class O >
using unary_transform_result = ranges::in_out_result<I, O>;
(5) (depuis C++20)
template< class I1, class I2, class O >
using binary_transform_result = ranges::in_in_out_result<I1, I2, O>;
(6) (depuis C++20)

Applique la fonction donnée à une plage et stocke le résultat dans une autre plage, en commençant à result.

1) L'opération unaire op est appliquée à la plage définie par [first1last1) (après projection avec la projection proj).
2) Identique à (1), mais utilise r comme plage source, comme si on utilisait ranges::begin(r) comme first et ranges::end(r) comme last.
3) L'opération binaire binary_op est appliquée à des paires d'éléments provenant de deux plages : l'une définie par [first1last1) et l'autre définie par [first2last2) (après projection respective avec les projections proj1 et proj2).
4) Identique à (3), mais utilise r1 comme première plage source, comme si on utilisait ranges::begin(r1) comme first1 et ranges::end(r1) comme last1, et de même pour r2.

Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithmes (informellement appelés niebloïdes), c'est-à-dire :

Paramètres

first1, last1 - la paire itérateur-sentinelle définissant la première plage d'éléments à transformer
r, r1 - la première plage d'éléments à transformer
first2, last2 - la paire itérateur-sentinelle définissant la seconde plage d'éléments à transformer
r2 - la seconde plage d'éléments à transformer
result - le début de la plage de destination, peut être égal à first1 ou first2
op, binary_op - opération à appliquer aux éléments projetés
proj1 - projection à appliquer aux éléments de la première plage
proj2 - projection à appliquer aux éléments de la seconde plage

Valeur de retour

1,2) Un unary_transform_result contient un itérateur d'entrée égal à last et un itérateur de sortie vers l'élément suivant le dernier élément transformé.
3,4) Un binary_transform_result contient des itérateurs d'entrée vers les derniers éléments transformés des plages [ first1 , last1 ) et [ first2 , last2 ) respectivement comme in1 et in2 , et l'itérateur de sortie vers l'élément suivant le dernier élément transformé comme out .

Complexité

1,2) Exactement ranges:: distance ( first1, last1 ) applications de op et proj .
3,4) Exactement ranges:: min ( ranges:: distance ( first1, last1 ) , ranges:: distance ( first2, last2 ) ) applications de binary_op et des projections.

Implémentation possible

struct transform_fn
{
    // Première version
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             std::copy_constructible F, class Proj = std::identity>
    requires std::indirectly_writable<O, std::indirect_result_t<F&,
                                                                std::projected<I, Proj>>>
    constexpr ranges::unary_transform_result<I, O>
        operator()(I first1, S last1, O result, F op, Proj proj = {}) const
    {
        for (; first1 != last1; ++first1, (void)++result)
            *result = std::invoke(op, std::invoke(proj, *first1));
        return {std::move(first1), std::move(result)};
    }
    // Deuxième version
    template<ranges::input_range R, std::weakly_incrementable O,
             std::copy_constructible F, class Proj = std::identity>
    requires std::indirectly_writable<O,
                 std::indirect_result_t<F&, std::projected<ranges::iterator_t<R>, Proj>>>
    constexpr ranges::unary_transform_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result, F op, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                       std::move(op), std::move(proj));
    }
    // Troisième version
    template<std::input_iterator I1, std::sentinel_for<I1> S1,
             std::input_iterator I2, std::sentinel_for<I2> S2,
             std::weakly_incrementable O,
             std::copy_constructible F,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires std::indirectly_writable<O,
                 std::indirect_result_t<F&,
                                        std::projected<I1, Proj1>,
                                        std::projected<I2, Proj2>>>
    constexpr ranges::binary_transform_result<I1, I2, O>
        operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                   F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        for (; first1 != last1 && first2 != last2;
             ++first1, (void)++first2, (void)++result)
            *result = std::invoke(binary_op,
                                  std::invoke(proj1, *first1),
                                  std::invoke(proj2, *first2));
        return {std::move(first1), std::move(first2), std::move(result)};
    }
    // Quatrième version
    template<ranges::input_range R1, ranges::input_range R2,
             std::weakly_incrementable O, std::copy_constructible F,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires std::indirectly_writable<O,
                 std::indirect_result_t<F&,
                     std::projected<ranges::iterator_t<R1>, Proj1>,
                     std::projected<ranges::iterator_t<R2>, Proj2>>>
    constexpr ranges::binary_transform_result<ranges::borrowed_iterator_t<R1>,
                                              ranges::borrowed_iterator_t<R2>, O>
        operator()(R1&& r1, R2&& r2, O result,
                   F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        return (*this)(ranges::begin(r1), ranges::end(r1),
                       ranges::begin(r2), ranges::end(r2),
                       std::move(result), std::move(binary_op),
                       std::move(proj1), std::move(proj2));
    }
};
inline constexpr transform_fn transform;

Notes

ranges::transform ne garantit pas l'application dans l'ordre de op ou binary_op . Pour appliquer une fonction à une séquence dans l'ordre ou pour appliquer une fonction qui modifie les éléments d'une séquence, utilisez ranges::for_each .

Exemple

Le code suivant utilise ranges::transform pour convertir une chaîne en place en majuscules en utilisant la fonction std::toupper puis transforme chaque char en sa valeur ordinale. Ensuite, ranges::transform avec une projection est utilisé pour transformer les éléments de std:: vector < Foo > en chars pour remplir une std::string .

#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
int main()
{
    std::string s{"hello"};
    auto op = [](unsigned char c) -> unsigned char { return std::toupper(c); };
    namespace ranges = std::ranges;
    // uppercase the string in-place
    ranges::transform(s.begin(), s.end(), s.begin(), op );
    std::vector<std::size_t> ordinals;
    // convert each char to size_t
    ranges::transform(s, std::back_inserter(ordinals),
                      [](unsigned char c) -> std::size_t { return c; });
    std::cout << s << ':';
    for (auto ord : ordinals)
        std::cout << ' ' << ord;
    // double each ordinal
    ranges::transform(ordinals, ordinals, ordinals.begin(), std::plus{});
    std::cout << '\n';
    for (auto ord : ordinals)
        std::cout << ord << ' ';
    std::cout << '\n';
    struct Foo { char bar; };
    const std::vector<Foo> f = {{'h'},{'e'},{'l'},{'l'},{'o'}};
    std::string result;
    // project, then uppercase
    ranges::transform(f, std::back_inserter(result), op, &Foo::bar);
    std::cout << result << '\n';
}

Sortie :

HELLO: 72 69 76 76 79
144 138 152 152 158
HELLO

Voir aussi

applique un objet fonction unaire aux éléments d'une plage
(objet fonction algorithme)
une view d'une séquence qui applique une fonction de transformation à chaque élément
(modèle de classe) (objet adaptateur de plage)
applique une fonction à une plage d'éléments, stockant les résultats dans une plage de destination
(modèle de fonction)