std::ranges:: uninitialized_default_construct
|
Definido en el encabezado
<memory>
|
||
|
Firma de llamada
|
||
|
template
<
no-throw-forward-iterator
I, no
-
throw
-
sentinel
-
for
<
I
>
S
>
requires
std::
default_initializable
<
std::
iter_value_t
<
I
>>
|
(1) |
(desde C++20)
(constexpr desde C++26) |
|
template
<
no-throw-forward-range
R
>
requires
std::
default_initializable
<
ranges::
range_value_t
<
R
>>
|
(2) |
(desde C++20)
(constexpr desde C++26) |
[
first
,
last
)
mediante
inicialización por defecto
, como si fuera
for
(
;
first
!
=
last
;
++
first
)
::
new
(
voidify
(
*
first
)
)
std::
remove_reference_t
<
std::
iter_reference_t
<
I
>>
;
return
first
;
Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:
- No se pueden especificar listas de argumentos de plantilla explícitas al llamar a cualquiera de ellos.
- Ninguno de ellos es visible para la búsqueda dependiente de argumento .
- Cuando cualquiera de ellos es encontrado mediante la búsqueda no calificada normal como el nombre a la izquierda del operador de llamada de función, la búsqueda dependiente de argumento queda inhibida.
Contenidos |
Parámetros
| first, last | - | el par iterador-sentinel que define el rango de elementos a inicializar |
| r | - |
el
range
de los elementos a inicializar
|
Valor de retorno
Como se describió anteriormente.
Complejidad
Lineal en la distancia entre first y last .
Excepciones
Cualquier excepción lanzada durante la construcción de los elementos en el rango de destino.
Notas
Una implementación puede omitir la construcción de objetos (sin cambiar el efecto observable) si no se llama a ningún constructor por defecto no trivial al inicializar por defecto un objeto std:: iter_value_t < I > , lo cual puede detectarse mediante std::is_trivially_default_constructible .
| Macro de prueba de características | Valor | Estándar | Característica |
|---|---|---|---|
__cpp_lib_raw_memory_algorithms
|
202411L
|
(C++26) | constexpr para algoritmos de memoria especializados , ( 1,2 ) |
Implementación posible
struct uninitialized_default_construct_fn { template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S> requires std::default_initializable<std::iter_value_t<I>> constexpr I operator()(I first, S last) const { using ValueType = std::remove_reference_t<std::iter_reference_t<I>>; if constexpr (std::is_trivially_default_constructible_v<ValueType>) return ranges::next(first, last); // omitir inicialización I rollback{first}; try { for (; !(first == last); ++first) ::new (static_cast<void*>(std::addressof(*first))) ValueType; return first; } catch (...) // retroceso: destruir elementos construidos { for (; rollback != first; ++rollback) ranges::destroy_at(std::addressof(*rollback)); throw; } } template<no-throw-forward-range R> requires std::default_initializable<ranges::range_value_t<R>> constexpr ranges::borrowed_iterator_t<R> operator()(R&& r) const { return (*this)(ranges::begin(r), ranges::end(r)); } }; inline constexpr uninitialized_default_construct_fn uninitialized_default_construct{}; |
Ejemplo
#include <cstring> #include <iostream> #include <memory> #include <string> int main() { struct S { std::string m{"▄▀▄▀▄▀▄▀"}; }; constexpr int n{4}; alignas(alignof(S)) char out[n * sizeof(S)]; try { auto first{reinterpret_cast<S*>(out)}; auto last{first + n}; std::ranges::uninitialized_default_construct(first, last); auto count{1}; for (auto it{first}; it != last; ++it) std::cout << count++ << ' ' << it->m << '\n'; std::ranges::destroy(first, last); } catch (...) { std::cout << "Exception!\n"; } // Nótese que para "tipos triviales" el uninitialized_default_construct // generalmente no rellena con ceros el área de memoria no inicializada dada. constexpr char sample[]{'A', 'B', 'C', 'D', '\n'}; char v[]{'A', 'B', 'C', 'D', '\n'}; std::ranges::uninitialized_default_construct(std::begin(v), std::end(v)); if (std::memcmp(v, sample, sizeof(v)) == 0) { std::cout << " "; // Comportamiento posiblemente indefinido, pendiente de resolución CWG 1997: // for (const char c : v) { std::cout << c << ' '; } for (const char c : sample) std::cout << c << ' '; } else std::cout << "No especificado\n"; }
Salida posible:
1 ▄▀▄▀▄▀▄▀ 2 ▄▀▄▀▄▀▄▀ 3 ▄▀▄▀▄▀▄▀ 4 ▄▀▄▀▄▀▄▀ A B C D
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 3870 | C++20 | este algoritmo podría crear objetos en un almacenamiento const | se mantiene no permitido |
Véase también
|
construye objetos mediante
default-initialization
en un área de memoria no inicializada, definida por un inicio y un contador
(objeto función de algoritmo) |
|
|
construye objetos mediante
value-initialization
en un área de memoria no inicializada, definida por un rango
(objeto función de algoritmo) |
|
|
construye objetos mediante
value-initialization
en un área de memoria no inicializada, definida por un inicio y un contador
(objeto función de algoritmo) |
|
|
(C++17)
|
construye objetos mediante
default-initialization
en un área de memoria no inicializada, definida por un rango
(plantilla de función) |