Namespaces
Variants

std::ranges:: uninitialized_move, std::ranges:: uninitialized_move_result

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Défini dans l'en-tête <memory>
Signature d'appel
template < std:: input_iterator I, std:: sentinel_for < I > S1,

no-throw-forward-iterator O, no - throw - sentinel - for < O > S2 >
requires std:: constructible_from < std:: iter_value_t < O > ,
std:: iter_rvalue_reference_t < I >>
uninitialized_move_result < I, O >

uninitialized_move ( I ifirst, S1 ilast, O ofirst, S2 olast ) ;
(1) (depuis C++20)
(constexpr depuis C++26)
template < ranges:: input_range IR, no-throw-forward-range OR >

requires std:: constructible_from
< ranges:: range_value_t < OR > ,
ranges:: range_rvalue_reference_t < IR >>
uninitialized_move_result < ranges:: borrowed_iterator_t < IR > ,
ranges:: borrowed_iterator_t < OR >>

uninitialized_move ( IR && in_range, OR && out_range ) ;
(2) (depuis C++20)
(constexpr depuis C++26)
Types auxiliaires
template < class I, class O >
using uninitialized_move_result = ranges:: in_out_result < I, O > ;
(3) (depuis C++20)

Soit N égal à ranges:: min ( ranges:: distance ( ifirst, ilast ) , ranges:: distance ( ofirst, olast ) ) .

1) Copie N éléments de [ ifirst , ilast ) (en utilisant la sémantique de déplacement si supportée) vers une zone mémoire non initialisée [ ofirst , olast ) comme par

for ( ; ifirst ! = ilast && ofirst ! = olast ; ++ ofirst, ( void ) ++ ifirst )
:: new ( voidify ( * ofirst ) )
std:: remove_reference_t < std:: iter_reference_t < O >> ( ranges:: iter_move ( ifirst ) ) ;
return { std :: move ( ifirst ) , ofirst } ;

Si une exception est levée durant l'initialisation, les objets déjà construits dans [ ofirst , olast ) sont détruits dans un ordre non spécifié. De plus, les objets dans [ ifirst , ilast ) qui ont déjà été déplacés sont laissés dans un état valide mais non spécifié.
2) Équivalent à return ranges :: uninitialized_move ( ranges:: begin ( in_range ) , ranges:: end ( in_range ) ,
ranges:: begin ( out_range ) , ranges:: end ( out_range ) ) ;
.

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

Table des matières

Paramètres

ifirst, ilast - la paire itérateur-sentinelle définissant la plage d'entrée des éléments à déplacer
in_range - la range d'entrée des éléments à déplacer
ofirst, olast - la paire itérateur-sentinelle définissant la plage de sortie des éléments à initialiser
out_range - la range de sortie à initialiser

Valeur de retour

Comme décrit ci-dessus.

Complexité

Linéaire en N .

Exceptions

Toute exception levée lors de la construction des éléments dans la plage de destination.

Notes

Une implémentation peut améliorer l'efficacité de ranges::uninitialized_move , par exemple en utilisant ranges::copy_n , si le type de valeur de la plage de sortie est TrivialType .

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr pour les algorithmes de mémoire spécialisés , ( 1,2 )

Implémentation possible

struct uninitialized_move_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S1,
             no-throw-forward-iterator O, no-throw-sentinel-for<O> S2>
        requires std::constructible_from<std::iter_value_t<O>,
                                         std::iter_rvalue_reference_t<I>>
    constexpr ranges::uninitialized_move_result<I, O>
        operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
    {
        using ValueType = std::remove_reference_t<std::iter_reference_t<O>>;
        O current{ofirst};
        try
        {
            for (; !(ifirst == ilast or current == olast); ++ifirst, ++current)
                ::new (static_cast<void*>(std::addressof(*current))))
                    ValueType(ranges::iter_move(ifirst));
            return {std::move(ifirst), std::move(current)};
        }
        catch (...) // restauration : détruire les éléments construits
        {
            for (; ofirst != current; ++ofirst)
                ranges::destroy_at(std::addressof(*ofirst));
            throw;
        }
    }
    template<ranges::input_range IR, no-throw-forward-range OR>
        requires std::constructible_from<ranges::range_value_t<OR>,
                                         ranges::range_rvalue_reference_t<IR>>
    constexpr ranges::uninitialized_move_result<ranges::borrowed_iterator_t<IR>,
                                                ranges::borrowed_iterator_t<OR>>
        operator()(IR&& in_range, OR&& out_range) const
    {
        return (*this)(ranges::begin(in_range), ranges::end(in_range),
                       ranges::begin(out_range), ranges::end(out_range));
    }
};
inline constexpr uninitialized_move_fn uninitialized_move{};

Exemple

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
void print(auto rem, auto first, auto last)
{
    for (std::cout << rem; first != last; ++first)
        std::cout << std::quoted(*first) << ' ';
    std::cout << '\n';
}
int main()
{
    std::string in[]{"Home", "World"};
    print("initially, in: ", std::begin(in), std::end(in));
    if (constexpr auto sz = std::size(in);
        void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first{static_cast<std::string*>(out)};
            auto last{first + sz};
            std::ranges::uninitialized_move(std::begin(in), std::end(in), first, last);
            print("after move, in: ", std::begin(in), std::end(in));
            print("after move, out: ", first, last);
            std::ranges::destroy(first, last);
        }
        catch (...)
        {
            std::cout << "Exception!\n";
        }
        std::free(out);
    }
}

Sortie possible :

initially, in: "Home" "World"
after move, in: "" ""
after move, out: "Home" "World"

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 3870 C++20 cet algorithme pourrait créer des objets sur un stockage const maintenu interdit

Voir aussi

déplace un nombre d'objets vers une zone mémoire non initialisée
(objet fonction algorithme)
déplace une plage d'objets vers une zone mémoire non initialisée
(modèle de fonction)