According to the Standard (N4659, §23.2.4, [utility.exchange]), std::exchange should do a std::move and a std::forward:
template <class T, class U = T> T exchange(T& obj, U&& new_val);Effects: Equivalent to:
T old_val = std::move(obj); obj = std::forward<U>(new_val); return old_val;
Both move and forward are marked as noexcept:
(N4659, §23.2.5, [forward]):
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;Returns:
static_cast<T&&>(t).(...)
template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;Returns:
static_cast<remove_reference_t<T>&&>(t).
So why isn't exchange noexcept? Is there some other reason for this or did the committee simply overlook this? Is this being proposed or can I write one?
Unlike std::swap, which by default only relies on move constructors and therefore should usually be noexcept, std::exchange may allocate resources if the new value needs to be copied. While there could probably be a complicated expression for a conditional noexcept when new_val is a U&& and neither the move assignment nor the old value's move throw, it seems nobody has made such a proposal
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With