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)
"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.