variant
's move assignment should not be guaranteed to produce a valueless by exception stateSection: 22.6.3.4 [variant.assign] Status: New Submitter: Brian Bi Opened: 2023-08-29 Last modified: 2023-10-30
Priority: 3
View other active issues in [variant.assign].
View all other issues in [variant.assign].
View all issues with New status.
Discussion:
22.6.3.4 [variant.assign] bullet 8.4 states that an alternative-changing move assignment on std::variant
is equivalent to a call to emplace
. However, bullet 10.1 also states that if the construction of the new
alternative exits via an exception, then the destination of the assignment is guaranteed to become valueless
by exception. This is inconsistent with the specification of emplace
, 22.6.3.5 [variant.mod]/11,
which permits (but does not require) the variant to become valueless.
[2023-10-30; Reflector poll]
Set priority to 3 after reflector poll.
"The remark is normatively redundant with the spec of emplace
,
strike it."
Proposed resolution:
This wording is relative to N4958.
Modify 22.6.3.4 [variant.assign] as indicated:
constexpr variant& operator=(variant&& rhs) noexcept(see below);-6- Let
[…] -8- Effects:j
berhs.index()
.
(8.1) — If neither
*this
norrhs
holds a value, there is no effect.(8.2) — Otherwise, if
*this
holds a value butrhs
does not, destroys the value contained in*this
and sets*this
to not hold a value.(8.3) — Otherwise, if
index() == j
, assignsget<j>(std::move(rhs))
to the value contained in*this
.(8.4) — Otherwise, equivalent to
emplace<j>(get<j>(std::move(rhs)))
.[…]
-10- Remarks: […]
(10.1) — If an exception is thrown during the call toTj
's move construction (withj
beingrhs.index()
), thevariant
will hold no value.
(10.2) —If an exception is thrown during the call toTj
's move assignment, the state of the contained value is as defined by the exception safety guarantee ofTj
's move assignment;index()
will bej
.