Namensräume
Varianten
Aktionen

std::uninitialized_copy_n

Von cppreference.com
< cpp‎ | memory
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
uninitialized_copy_n
(C++11)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
Definiert in Header <memory>
template< class InputIt, class Size, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_copy_n( InputIt first, Size count,

                                       NoThrowForwardIt d_first );
(1) (seit C++11)
(constexpr seit C++26)
template< class ExecutionPolicy, class ForwardIt,

          class Size, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy_n( ExecutionPolicy&& policy,
                                       ForwardIt first, Size count,

                                       NoThrowForwardIt d_first );
(2) (seit C++17)
1) Kopiert count Elemente aus einem Bereich, der bei first beginnt, in einen uninitialisierten Speicherbereich, der bei d_first beginnt, als ob durch

for (; count > 0; ++d_first, (void) ++first, --count)
    ::new (voidify(*d_first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(*first);

Wenn während der Initialisierung eine Ausnahme ausgelöst wird, werden die bereits konstruierten Objekte in nicht spezifizierter Reihenfolge zerstört.
2) Wie (1), wird aber gemäß policy ausgeführt.
Diese Überladung nimmt an der Überladungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true.

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true.

(seit C++20)


Wenn d_first + [0count) mit first + [0count) überlappt, ist das Verhalten undefiniert.

(seit C++20)

Inhalt

[bearbeiten] Parameter

first - Der Beginn des Bereichs der zu kopierenden Elemente
zählt - Die Anzahl der zu kopierenden Elemente
d_first - der Anfang des Zielbereichs
policy - die Ausführungsrichtlinie, die verwendet werden soll
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
NoThrowForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
Keine Inkrement-, Zuweisungs-, Vergleichs- oder Dereferenzierungsoperationen über gültige Instanzen von NoThrowForwardIt dürfen Ausnahmen auslösen.

[bearbeiten] Rückgabewert

Iterator auf das Element nach dem letzten kopierten Element.

[bearbeiten] Komplexität

Linear in count.

[bearbeiten] Ausnahmen

Die Überladung mit einem Template-Parameter namens ExecutionPolicy meldet Fehler wie folgt

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[bearbeiten] Anmerkungen

Feature-Test-Makro Wert Std Feature
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr für spezialisierte Speicher-Algorithmen, (1)

[bearbeiten] Mögliche Implementierung

template<class InputIt, class Size, class NoThrowForwardIt>
constexpr NoThrowForwardIt uninitialized_copy_n(InputIt first, Size count,
                                                NoThrowForwardIt d_first)
{
    using T = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = d_first;
    try
    {
        for (; count > 0; ++first, (void) ++current, --count)
            ::new (static_cast<void*>(std::addressof(*current))) T(*first);
    }
    catch (...)
    {
        for (; d_first != current; ++d_first)
            d_first->~T();
        throw;
    }
    return current;
}

[bearbeiten] Beispiel

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
 
int main()
{
    std::vector<std::string> v = {"This", "is", "an", "example"};
 
    std::string* p;
    std::size_t sz;
    std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
    sz = std::min(sz, v.size());
 
    std::uninitialized_copy_n(v.begin(), sz, p);
 
    for (std::string* i = p; i != p + sz; ++i)
    {
        std::cout << *i << ' ';
        i->~basic_string<char>();
    }
    std::cout << '\n';
 
    std::return_temporary_buffer(p);
}

Mögliche Ausgabe

This is an example

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2133 C++98 Die Effektbeschreibung verwendete eine for-Schleife mit der Iteration
Ausdruck ++d_first, ++first, --count, was
zu argumentabhängigen Lookups von operator, führt
verwirft den Wert
eines Operanden für
deaktiviert diese ADLs
LWG 2433 C++11 dieser Algorithmus kann durch überladenes operator& gekapert werden verwendet std::addressof
LWG 3870 C++20 dieser Algorithmus kann Objekte auf einem const Speicher erstellen nicht erlaubt

[bearbeiten] Siehe auch

kopiert einen Bereich von Objekten in einen uninitialisierten Speicherbereich
(Funktions-Template) [edit]
kopiert eine Anzahl von Objekten in einen uninitialisierten Speicherbereich
(Algorithmus-Funktionsobjekt)[edit]