std::uninitialized_copy
Von de.cppreference.net
| Definiert in Header <memory>
|
||
template< class InputIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy( InputIt first, InputIt last,
NoThrowForwardIt d_first );
|
(1) | (constexpr seit C++26) |
template< class ExecutionPolicy, class ForwardIt,
class NoThrowForwardIt >
NoThrowForwardIt uninitialized_copy( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
NoThrowForwardIt d_first );
|
(2) | (seit C++17) |
1) Konstruiert Elemente im Zielbereich, beginnend bei
d_first, aus Elementen im Quellbereich [first, last) wie durch
for (; first != last; ++d_first, (void) ++first)
::new (voidify(*d_first))
typename std::iterator_traits<NoThrowForwardIt>::value_type(*first);
return d_first;
Wenn während der Initialisierung eine Ausnahme ausgelöst wird, werden die bereits konstruierten Objekte in einer nicht spezifizierten Reihenfolge zerstört.
2) Gleich wie (1), aber ausgeführt gemäß
policy. Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks
true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
|
Wenn |
(seit C++20) |
Parameter
| first, last | - | das Paar von Iteratoren, das den Bereich der zu kopierenden Elemente definiert |
| d_first | - | der Anfang des Zielbereichs |
| policy | - | die zu verwendende Ausführungsrichtlinie |
| 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.
|
||
-
NoThrowForwardIt
darf Ausnahmen werfen.
Die Anwendung von
&
*
auf einen
NoThrowForwardIt
-Wert muss einen Zeiger auf seinen Werttyp liefern.
(bis C++11)
|
||
Rückgabewert
Wie oben beschrieben.
Ausnahmen
2) Während des Ausführungsprozesses:
- Falls die temporären Speicherressourcen, die für die Parallelisierung benötigt werden, nicht verfügbar sind, std::bad_alloc wird ausgelöst.
- Falls eine nicht abgefangene Ausnahme beim Zugriff auf Objekte über ein Algorithmusargument ausgelöst wird, wird das Verhalten von der Ausführungsrichtlinie bestimmt (für standard policies, std::terminate aufgerufen wird).
Anmerkungen
| Feature-Test Makro | Wert | Norm | Feature |
|---|---|---|---|
__cpp_lib_raw_memory_algorithms |
202411L |
(C++26) | constexpr für spezialisierte <memory> Algorithmen, (1)
|
Mögliche Implementierung
template<class InputIt, class NoThrowForwardIt> constexpr NoThrowForwardIt uninitialized_copy(InputIt first, InputIt last, NoThrowForwardIt d_first) { using T = typename std::iterator_traits<NoThrowForwardIt>::value_type; NoThrowForwardIt current = d_first; try { for (; first != last; ++first, (void) ++current) ::new (static_cast<void*>(std::addressof(*current))) T(*first); return current; } catch (...) { for (; d_first != current; ++d_first) d_first->~T(); throw; } } |
Beispiel
Diesen Code ausführen
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
int main()
{
const char* v[] = {"This", "is", "an", "example"};
auto sz = std::size(v);
if (void* pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
{
try
{
auto first = static_cast<std::string*>(pbuf);
auto last = std::uninitialized_copy(std::begin(v), std::end(v), first);
for (auto it = first; it != last; ++it)
std::cout << *it << '_';
std::cout << '\n';
std::destroy(first, last);
}
catch (...) {}
std::free(pbuf);
}
}
Ausgabe:
This_is_an_example_
Fehlerberichte
Die folgenden verhaltensverändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Richtiges Verhalten |
|---|---|---|---|
| LWG 866 | C++98 | gegeben T als Werttyp von NoThrowForwardIt, fallsT::operator new existiert, könnte das Programm fehlerhaft sein
|
verwendet stattdessen globales replacement- new |
| LWG 2133 | C++98 | die Effektbeschreibung verwendete eine for Schleife mit dem Iterationsausdruck ++d_first, ++first, was zu einer argumentabhängigen Suche nach operator,
|
führt; verwirft den Wert eines Operanden um dieses ADL zu deaktivieren |
| LWG 2433 | C++11 | dieser Algorithmus könnte durch überladene operator&
|
gekapert werden; verwendet std::addressof |
Siehe auch
|
(C++11)
|
kopiert eine Anzahl von Objekten in einen nicht initialisierten Speicherbereich
(Funktions-Template) |
|
(C++20)
|
kopiert einen Bereich von Objekten in einen nicht initialisierten Speicherbereich
(Algorithmus-Funktionsobjekt) |