std::ranges::uninitialized_default_construct() algorithm
- od C++20
- Simplified
- Detailed
// (1)
I uninitialized_default_construct( I first, S last );
// (2)
ranges::borrowed_iterator_t<R>
uninitialized_default_construct( R&& r );
The type of arguments are generic and have following constraints:
I-no-throw-forward-iteratorS-no-throw-sentinel-for<I>R-no-throw-forward-range
Additionally, each overload has the following constraints:
- (1)
std::default_initializable<std::iter_value_t<I>> - (2)
std::default_initializable<ranges::range_value_t<R>>
// (1)
template<
no-throw-forward-iterator I,
no-throw-sentinel-for<I> S
>
requires std::default_initializable<std::iter_value_t<I>>
I uninitialized_default_construct( I first, S last );
// (2)
template< no-throw-forward-range R >
requires std::default_initializable<ranges::range_value_t<R>>
ranges::borrowed_iterator_t<R>
uninitialized_default_construct( R&& r );
-
(1) Constructs objects of type
std::iter_value_t<I>in the uninitialized storage designated by the range [first;last) bydefault-initialization, as if by:for (; first != last; ++first)
::new (static_cast<void*>(std::addressof(*first)))
std::remove_reference_t<std::iter_reference_t<I>>;uwagaIf an exception is thrown during the initialization, the objects already constructed are destroyed in an unspecified order.
-
(2) Same as (1), but uses
ras the range, as if usingranges::begin(r)asfirst, andranges::end(r)aslast.
The function-like entities described on this page are niebloids.
Parameters
first last | The range of elements to initialize. |
r | The range of elements to initialize. |
Return value
An iterator equal to last.
Complexity
Linear in the distance between first and last.
Exceptions
The exception thrown on construction of the elements in the destination range, if any.
Possible implementation
uninitialized_default_construct(1) and uninitialized_default_construct(2)
Notes
An implementation may skip the objects construction (without changing the observable effect) if no non-trivial
default constructor is called while default-initializing a std::iter_value_t<I> object, which can be detected by
std::is_trivially_default_constructible_v.
Examples
#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"; }
// Notice that for "trivial types" the uninitialized_default_construct
// generally does not zero-fill the given uninitialized memory area.
constexpr char etalon[]{'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, etalon, sizeof(v)) == 0)
{
std::cout << " ";
// Maybe undefined behavior, pending CWG 1997:
// for (const char c : v) { std::cout << c << ' '; }
for (const char c : etalon)
std::cout << c << ' ';
}
else
std::cout << "Unspecified\n";
}
1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀
A B C D
Hover to see the original license.