Created on 2017-02-03.00:00:00 last changed 90 months ago
Proposed resolution:
This wording is relative to N4640.
Modify [variant.assign] as indicated:
[Drafting note: Presentation of para 9 immediately below has been split into individual bullets.]
variant& operator=(const variant& rhs);Let j be rhs.index().
-1- Effects:
(1.1) — If neither *this nor rhs holds a value, there is no effect. Otherwise,
(1.2) — if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value. Otherwise,
(1.3) — if index() == j
rhs.index(), assigns the value contained in rhs to the value contained in *this. Otherwise,(1.?) — if is_nothrow_copy_constructible_v<Tj> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(get<j>(rhs)). Otherwise,
(1.4) — equivalent to operator=(variant(rhs))
copies the value contained in rhs to a temporary, then destroys any value contained in *this. Sets *this to hold the same alternative index as rhs and initializes the value contained in *this as if direct-non-list-initializing an object of type Tj with std::forward<Tj>(TMP), with TMP being the temporary and j being rhs.index().-2- Returns: *this.
-3- Postconditions: index() == rhs.index(). -4- Remarks: This function shall not participate in overload resolution unless is_copy_constructible_v<Ti>&& is_move_constructible_v<Ti>&& is_copy_assignable_v<Ti> is true for all i.
(4.1) — If an exception is thrown during the call […]
(4.2) — If an exception is thrown during the call […]
(4.3) — If an exception is thrown during the call […]variant& operator=(variant&& rhs) noexcept(see below);Let j be rhs.index().
-5- Effects:
(5.1) — If neither *this nor rhs holds a value, there is no effect. Otherwise,
(5.2) — if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value. Otherwise,
(5.3) — if index() == j
rhs.index(), assigns get<j>(std::move(rhs)) to the value contained in *this, with j being index(). Otherwise,(5.4) — equivalent to emplace<j>(get<j>(std::move(rhs)))
destroys any value contained in *this. Sets *this to hold the same alternative index as rhs and initializes the value contained in *this as if direct-non-list-initializing an object of type Tj with get<j>(std::move(rhs)) with j being rhs.index().[…]
[…]
template <class T> variant& operator=(T&& t) noexcept(see below);-8- […]
-9- Effects:
(9.1) — If *this holds a Tj, assigns std::forward<T>(t) to the value contained in *this. Otherwise,
(9.?) — if is_nothrow_constructible_v<Tj, T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(std::forward<T>(t)). Otherwise,
(9.3) — equivalent to operator=(variant(std::forward<T>(t)))
destroys any value contained in *this, sets *this to hold the alternative type Tj as selected by the imaginary function overload resolution described above, and direct-initializes the contained value as if direct-non-list-initializing it with std::forward<T>(t).
[ Kona 2017-03-02 ]
Accepted as Immediate to resolve NB comment.
[ 2017-03-02, Kona, Casey comments and suggests wording ]
The wording below has been developed with much input from Tomasz.
The copy-assignment operator is very careful to not destroy the contained element until after a temporary has been constructed, which can be safely moved from.
This makes the valueless_by_exception state extremely rare, by design.
However, the same care and attention is not paid to the move-assignment operator, nor the assignment-from-deduced-value assignment template. This concern should be similarly important in these cases, especially the latter.
Proposed change: —
History | |||
---|---|---|---|
Date | User | Action | Args |
2017-07-30 20:15:43 | admin | set | status: wp -> c++17 |
2017-03-05 23:46:08 | admin | set | status: immediate -> wp |
2017-03-03 22:14:37 | admin | set | messages: + msg9070 |
2017-03-03 22:14:37 | admin | set | status: new -> immediate |
2017-03-02 06:10:17 | admin | set | messages: + msg9034 |
2017-03-02 06:10:17 | admin | set | messages: + msg9033 |
2017-02-03 00:00:00 | admin | create |