-
Notifications
You must be signed in to change notification settings - Fork 17
Closed
Description
I'm wondering about the interactions between optional<T&> and optional<T>. Specifically about optional<T>'s "converting" move constructor when the RHS is a optional<T&>. Should there be a move from the "remote" value, or should the value category be shallow, leading to a copy? Example:
{
std::string s = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm";
beman::optional26::optional<std::string&> o1 = s;
beman::optional26::optional<std::string> o2 = std::move(o1);
EXPECT_???(s.empty());
}At the moment, there is a move happening, and s is empty. I'm not sure if this is intended behavior though, or a "happy accident".
In any case, the "converting" move constructor of optional<T> seems not yet aware of optional<T&>:
/// Converting move constructor.
template <class T>
template <class U>
inline constexpr optional<T>::optional(optional<U>&& rhs)
requires detail::enable_from_other<T, U, U&&> && std::is_convertible_v<U&&, T>
{
if (rhs.has_value()) {
construct(std::move(*rhs));
}
}...if U is a reference here, the U&&'s collapse to simple references. So detail::enable_from_other actually checks if it can copy the value of the rhs in the constraints, but then does a move inside the function body.
Metadata
Metadata
Assignees
Labels
No labels