std::uninitialized_move
From cppreference.com
| Defined in header <memory>
|
||
template< class InputIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( InputIt first, InputIt last,
NoThrowForwardIt d_first );
|
(1) | (since C++17) (constexpr since C++26) |
template< class ExecutionPolicy,
class ForwardIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
NoThrowForwardIt d_first );
|
(2) | (since C++17) |
1) Constructs elements in the destination range beginning at
d_first from elements in the source range [first, last) as if by
for (; first != last; ++d_first, (void) ++first)
::new (voidify(*d_first))
typename std::iterator_traits<NoThrowForwardIt>::value_type(deref-move(*iter));
return d_first;
If an exception is thrown during the initialization, some objects in
[first, last) are left in a valid but unspecified state, and the objects already constructed are destroyed in an unspecified order.2) Same as (1), but executed according to
policy. This overload participates in overload resolution only if the value of the following expression is
true:
|
|
(until C++20) |
|
|
(since C++20) |
|
If |
(since C++20) |
Parameters
| first, last | - | the pair of iterators defining the range of elements to move |
| d_first | - | the beginning of the destination range |
| policy | - | the execution policy to use |
| Type requirements | ||
-InputIt must meet the requirements of LegacyInputIterator.
| ||
-ForwardIt must meet the requirements of LegacyForwardIterator.
| ||
-NoThrowForwardIt must meet the requirements of LegacyForwardIterator.
| ||
-No increment, assignment, comparison, or indirection through valid instances of NoThrowForwardIt may throw exceptions.
| ||
Return value
As described above.
Exceptions
2) During the execution process:
- If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
- If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).
Notes
When the input iterator deferences to an rvalue, the behavior of std::uninitialized_move is same as std::uninitialized_copy.
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_raw_memory_algorithms |
202411L |
(C++26) | constexpr for specialized <memory> algorithms, (1)
|
Possible implementation
template<class InputIt, class NoThrowForwardIt>
constexpr NoThrowForwardIt uninitialized_move(InputIt first, InputIt last,
NoThrowForwardIt d_first)
{
using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
auto current = d_first;
try
{
for (; first != last; ++first, (void) ++current)
{
auto addr = static_cast<void*>(std::addressof(*current));
if constexpr (std::is_lvalue_reference_v<decltype(*first)>)
::new (addr) ValueType(std::move(*first));
else
::new (addr) ValueType(*first);
}
return current;
}
catch (...)
{
std::destroy(d_first, current);
throw;
}
}
|
Example
Run this code
#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", "Work!"};
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::uninitialized_move(std::begin(in), std::end(in), first);
print("after move, in: ", std::begin(in), std::end(in));
print("after move, out: ", first, last);
std::destroy(first, last);
}
catch (...)
{
std::cout << "Exception!\n";
}
std::free(out);
}
}
Possible output:
initially, in: "Home" "Work!"
after move, in: "" ""
after move, out: "Home" "Work!"
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3918 | C++17 | move constuction is always performed even if the input iterator deferences to a prvalue |
no move construction in this case |
See also
| copies a range of objects to an uninitialized area of memory (function template & algorithm function object) | |
(C++20) |
|
(C++17) |
moves a number of objects to an uninitialized area of memory (function template & algorithm function object) |
(C++20) |
|
(C++20) |
moves a range of objects to an uninitialized area of memory (algorithm function object) |