Concept Subspace :: sus :: mem :: IsMoveRef
template <class T>concept IsMoveRef
std::is_rvalue_reference_v<T>
!std::is_const_v<std::remove_reference_t<T>>
A concept that can be used to constrain a universal reference parameter to ensure the caller provides something that was moved from, akin to receiving by value. This avoids inadvertantly moving out of an lvalue in the caller.
Always invoke IsMoveRef with the decltype
of the argument being tested to
ensure the correct type is tested, such as IsMoveRef<decltype(arg)>
.
In the common case, when you want to receive a parameter that will be moved, it should be received by value. However, library implementors sometimes with to receive an rvalue reference. That is a reference to an rvalue which can be moved from. This is unfortunately spelled the same as a universal reference, so it will also bind to an lvalue in the caller, and moving from the reference would move from the caller's lvalue.
To receive an rvalue reference (and not a universal reference), constrain
the input universal reference T&& t
by the IsMoveRef
concept with
requires(IsMoveRef<decltype(t)>)
. When this is satisfied, the input will
need to be an rvalue. In this case, sus::move()
will always perform a move
from an rvalue and will not move out of an lvalue in the caller.
sus::forward<T>
can also be used with universal references, but when
constructing a value type T
it will implicitly copy from const
references.