template<typename T, typename U>
constexpr std::remove_reference_t<T>&& move_as(U& u) noexcept
{
    return static_cast<T&&>(static_cast<U&&>(u));
}

Would work as a possible implementation (example)

On 04.06.2025 11:13, Tymi wrote:

"moving" meaning "using std::move" meaning casting to an rvalue reference, let's not point such things out when we know what we are talking about :/


> I don't think your std:: expected example works, it didn't have a conversion operator. What you want is just std:: move(*exp) or *std::move(exp).

My std::expected example does not currently work, but std::move_as opens a possibility for std::expected to implement such a conversion. std::move(*myExpected) works, but std::move_as<Value>(myExpected) seems cleaner to me.

> And your string example works with just static_cast<std::string&&>(obj).

And no, static_cast<std::string&&>(obj) does not work.

On 04.06.2025 11:08, Jonathan Wakely wrote:


On Wed, 4 Jun 2025, 09:03 Tymi via Std-Proposals, <std-proposals@lists.isocpp.org> wrote:
I find the move_as example more intuitive and generally "safer". Also my first thought was that std::string(std::move(c)) copied c._value and created a new object out of it, instead of just moving c._value.

You seem to be saying "moving" when you mean "casting to rvalue reference", which is not moving. 


I don't think your std:: expected example works, it didn't have a conversion operator. What you want is just std:: move(*exp) or *std::move(exp).

And your string example works with just static_cast<std::string&&>(obj).

So I think the existing solutions are fine.