This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.
2753. Optional's constructors and assignments need constraintsSection: 22.5.3.2 [optional.ctor], 22.5.3.4 [optional.assign] Status: Resolved Submitter: Casey Carter Opened: 2016-07-22 Last modified: 2017-06-15
Priority: 0
View all other issues in [optional.ctor].
View all issues with Resolved status.
Discussion:
To use optional<T>
as if it were a T
in generic contexts, optional<T>
's "generic" operations must behave as do those of T
under overload resolution. At minimum, optional
's constructors and assignment operators should not participate in overload resolution with argument types that cannot be used to construct/assign the contained T
so that is_constructible_v<optional<T>, Args...>
(respectively is_assignable_v<optional<T>&, RHS>
) is equivalent to is_constructible_v<T, Args...>
(respectively is_assignable_v<T&, RHS>
).
In passing, note that the Requires element for optional
's in-place initializer_list
constructor unnecessarily duplicates its Remarks element; it should be removed.
It should also be noted that the resolution of LWG 2451(i) adds constructors to optional
with appropriate constraints, but does not constrain the additional assignment operators. If LWG chooses to apply the resolution of 2451 to the WP, the Requires elements of the additional assignment operators should also be converted to constraints as the wording herein does for the assignment operators in N4606.
[2016-07 Chicago]
Monday: P0 - tentatively ready
[2016-11-28 Post-Issaquah]
Resolved by the adoption of 2756(i)
Proposed resolution:
This wording is relative to N4606.
Remove [optional.object.ctor] p3, and add a new paragraph after p6:
optional(const optional<T>& rhs);-3- Requires:
[…] -?- Remarks: The function shall not participate in overload resolution unlessis_copy_constructible_v<T>
istrue
.is_copy_constructible_v<T>
istrue
.
Remove [optional.object.ctor] p7, and change p11 to:
optional(optional<T>&& rhs) noexcept(see below);-7- Requires:
[…] -11- Remarks: The expression insideis_move_constructible_v<T>
istrue
.noexcept
is equivalent tois_nothrow_move_constructible_v<T>
. The function shall not participate in overload resolution unlessis_move_constructible_v<T>
istrue
.
Remove [optional.object.ctor] p12, and change p16 to:
constexpr optional(const T& v);-12- Requires:
[…] -16- Remarks: Ifis_copy_constructible_v<T>
istrue
.T
's selected constructor is aconstexpr
constructor, this constructor shall be aconstexpr
constructor. The function shall not participate in overload resolution unlessis_copy_constructible_v<T>
istrue
.
Remove [optional.object.ctor] p17, and change p21 to:
constexpr optional(T&& v);-17- Requires:
[…] -21- Remarks: Ifis_move_constructible_v<T>
istrue
.T
's selected constructor is aconstexpr
constructor, this constructor shall be aconstexpr
constructor. The function shall not participate in overload resolution unlessis_move_constructible_v<T>
istrue
.
Remove [optional.object.ctor] p22, and change p26 to:
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);-22- Requires:
[…] -26- Remarks: Ifis_constructible_v<T, Args&&...>
istrue
.T
's constructor selected for the initialization is aconstexpr
constructor, this constructor shall be aconstexpr
constructor. The function shall not participate in overload resolution unlessis_constructible_v<T, Args...>
istrue
.
Remove [optional.object.ctor] p27.
template <class U, class... Args> constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);-27- Requires:
[…]is_constructible_v<T, initializer_list<U>&, Args&&...>
istrue
.
Remove [optional.object.assign] p4, and change p8 to:
optional<T>& operator=(const optional<T>& rhs);-4- Requires:
[…] -8- Remarks: If any exception is thrown, the result of the expressionis_copy_constructible_v<T>
istrue
andis_copy_assignable_v<T>
istrue
.bool(*this)
remains unchanged. If an exception is thrown during the call toT
's copy constructor, no effect. If an exception is thrown during the call toT
's copy assignment, the state of its contained value is as defined by the exception safety guarantee ofT
's copy assignment. The function shall not participate in overload resolution unlessis_copy_constructible_v<T> && is_copy_assignable_v<T>
istrue
.
Remove [optional.object.assign] p9, and add a new paragraph after p14:
optional<T>& operator=(optional<T>&& rhs) noexcept(see below);-9- Requires:
[…] -14- Remarks: […] If an exception is thrown during the call tois_move_constructible_v<T>
istrue
andis_move_assignable_v<T>
istrue
.T
's move assignment, the state of*val
and*rhs.val
is determined by the exception safety guarantee ofT
's move assignment. The function shall not participate in overload resolution unlessis_move_constructible_v<T> && is_move_assignable_v<T>
istrue
.
Remove [optional.object.assign] p15, and change p19 to (yes, this wording is odd - the intent is that it will "do the right thing" after incorporation of LWG 2451(i)):
template <class U> optional<T>& operator=(U&& v);-15- Requires:
[…] -19- Remarks: If any exception is thrown, the result of the expressionis_constructible_v<T, U>
istrue
andis_assignable_v<T&, U>
istrue
.bool(*this)
remains unchanged. If an exception is thrown during the call toT
's constructor, the state ofv
is determined by the exception safety guarantee ofT
's constructor. If an exception is thrown during the call toT
's assignment, the state of*val
andv
is determined by the exception safety guarantee ofT
's assignment. The function shall not participate in overload resolution unlessis_same_v<decay_t<U>, T> && is_constructible_v<T, U> && is_assignable_v<T&, U>
istrue
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4