10

C++17 adds std::uninitialized_move, but there is no std::uninitialized_move_if_noexcept that would use std::move_if_noexcept internally. In my opinion, it would be useful, since now, if we want to reallocate, we still need to write something as

if constexpr (!std::is_nothrow_move_constructible_v<value_type>
              && std::is_copy_constructible_v<value_type>)
  std::uninitialized_copy(...);
else 
  std::uninitialized_move(...); 

Are there any particular reasons why std::uninitialized_move_if_noexcept was not introduced in C++17?

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93

1 Answers1

10

A paper on "Extending memory management tools" at open-std.org has a section on uninitialized_move which deals with this matter.

Some concern is raised about exception handling with respect to uninitialized_move. If a move-constructor throws, the source object may have been irreparably damaged. As there is no solution to this problem, we implement the natural and expected semantics of destroying all fully constructed objects in the destination buffer and propagating the exception. This matches the behavior of uninitialized_copy as closely as possible. An additional algorithm, uninitialized_move_if_noexcept, could be considered as a resolution to this concern. Such an algorithm was found already implemented in libstdc++ using a move_if_noexcept iterator. Given that there is currently no range-based move_if_noexcept algorithm, such a solution is not considered here. It seems clear that such a feature is readily possible, however.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • What is `move_if_noexcept` iterator? There is only `std::move_iterator` in the Standard library, but no `std::move_if_noexcept_iterator`. – Daniel Langr Oct 23 '18 at 07:59
  • Methinks the paper is referring to this: https://en.cppreference.com/w/cpp/utility/move_if_noexcept – P.W Oct 23 '18 at 08:04
  • Actually, `uninitialized_move` could simply copy-assign all fully constructed objects from the destination buffer back to the source buffer, if the type is nothrow copy assignable. Then destroying all fully constructed objects in the destination buffer as it does anyway. This approach is also readily possible. This is still a weak/basic exception guarantee, but still better than leaving all fully moved-from objects in unspecified, but valid state. This way all the objects that could be revived is revived. – plasmacel May 11 '20 at 02:15