This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of LEWG status.
Section: 27.11.6 [uninitialized.move] Status: LEWG Submitter: Jiang An Opened: 2023-04-04 Last modified: 2023-06-01
Priority: 3
View all issues with LEWG status.
Discussion:
Currently std::move is unconditionally used in std::uninitialized_move and std::uninitialized_move_n, which may involve unnecessary move construction if dereferencing the input iterator yields a prvalue.
The status quo was mentioned in paper issue #975, but no further process is done since then.[2023-06-01; Reflector poll]
Set priority to 3 after reflector poll. Send to LEWG.
"P2283 wants to remove guaranteed elision here."
"Poorly motivated, not clear anybody is using these algos with proxy iterators."
"Consider using iter_move
in the move algos."
Proposed resolution:
This wording is relative to N4944.
Modify 27.11.1 [specialized.algorithms.general] as indicated:
-3- Some algorithms specified in 27.11 [specialized.algorithms] make use of the following exposition-only functions
voidify:template<class T> constexpr void* voidify(T& obj) noexcept { return addressof(obj); } template<class I> decltype(auto) deref-move(const I& it) { if constexpr (is_lvalue_reference_v<decltype(*it)>) return std::move(*it); else return *it; }
Modify 27.11.6 [uninitialized.move] as indicated:
template<class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, NoThrowForwardIterator result);[…]-1- Preconditions: result + [0, (last - first)) does not overlap with [first, last).
-2- Effects: Equivalent to:for (; first != last; (void)++result, ++first) ::new (voidify(*result)) typename iterator_traits<NoThrowForwardIterator>::value_type(std::move(*deref-move(first)); return result;template<class InputIterator, class Size, class NoThrowForwardIterator> pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);-6- Preconditions: result + [0, n) does not overlap with first + [0, n).
-7- Effects: Equivalent to:for (; n > 0; ++result,(void) ++first, --n) ::new (voidify(*result)) typename iterator_traits<NoThrowForwardIterator>::value_type(std::move(*deref-move(first)); return {first, result};