implementation of std::exchange is not clear...

Some code from the standard that has some tricks I do not understand:


1
2
3
4
5
6
7
8
EXPORT_STD template <class _Ty, class _Other = _Ty>
_CONSTEXPR20 _Ty exchange(_Ty& _Val, _Other&& _New_val) noexcept(
    conjunction_v<is_nothrow_move_constructible<_Ty>, is_nothrow_assignable<_Ty&, _Other>>) {
    // assign _New_val to _Val, return previous _Val
    _Ty _Old_val = static_cast<_Ty&&>(_Val);
    _Val         = static_cast<_Other&&>(_New_val);
    return _Old_val;
}



why is _New_val cast to Other&&, New_val is already Other&&!!

is this to provoke a move assignment?

The same goes for _Val??

Thanks

If t is a forwarding reference of type T, static_cast<T&&>(t) is equivalent to std::forward<T>(t).

In this example _Val and _New_val are forwarding references, so the implementation is equivalent to
1
2
3
4
5
6
7
8
EXPORT_STD template <class _Ty, class _Other = _Ty>
_CONSTEXPR20 _Ty exchange(_Ty& _Val, _Other&& _New_val) noexcept(
    conjunction_v<is_nothrow_move_constructible<_Ty>, is_nothrow_assignable<_Ty&, _Other>>) {
    // assign _New_val to _Val, return previous _Val
    _Ty _Old_val = std::forward<_Ty>(_Val);
    _Val         = std::forward<_Other>(_New_val);
    return _Old_val;
}

This is sometimes done in library code to avoid depending on std::forward.
Last edited on
but _Val is not a forwarding reference; it is a simple reference of type _Ty&...
so static_cast<_Ty&&>(_Val) is equivalent to std::move(_Val)

Am I wrong?

No, you're right. I misread.
Topic archived. No new replies allowed.