This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
std::pair::operator=
Section: 22.3.2 [pairs.pair], 22.4.4.3 [tuple.assign] Status: C++17 Submitter: Richard Smith Opened: 2016-06-07 Last modified: 2017-07-30
Priority: 2
View other active issues in [pairs.pair].
View all other issues in [pairs.pair].
View all issues with C++17 status.
Discussion:
std::is_copy_assignable<std::pair<int, std::unique_ptr<int>>>::value
is true
, and
should be false
. We're missing a "shall not participate in overload resolution unless" for pair
's
operator=
, and likewise for tuple
.
[2016-08-03 Chicago LWG]
Inspired by Eric Fiselier and Ville, Walter and Nevin provide initial Proposed Resolution.
[2016-08 - Chicago]
Thurs PM: Moved to Tentatively Ready
Lots of discussion, but no one had a better idea.
Proposed resolution:
This wording is relative to N4606.
Change 22.3.2 [pairs.pair] as indicated:
pair& operator=(const pair& p);-15-
[…]RequiresRemarks: This operator shall be defined as deleted unlessis_copy_assignable_v<first_type>
istrue
andis_copy_assignable_v<second_type>
istrue
.template<class U, class V> pair& operator=(const pair<U, V>& p);-18-
[…]RequiresRemarks: This operator shall not participate in overload resolution unlessis_assignable_v<first_type&, const U&>
istrue
andis_assignable_v<second_type&, const V&>
istrue
.pair& operator=(pair&& p) noexcept(see below);-21- Remarks: The expression inside
noexcept
is equivalent to:is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>-22-
[…]RequiresRemarks: This operator shall be defined as deleted unlessis_move_assignable_v<first_type>
istrue
andis_move_assignable_v<second_type>
istrue
.template<class U, class V> pair& operator=(pair<U, V>&& p);-25-
RequiresRemarks: This operator shall not participate in overload resolution unlessis_assignable_v<first_type&, U&&>
istrue
andis_assignable_v<second_type&, V&&>
istrue
.
Change 22.4.4.3 [tuple.assign] as indicated:
tuple& operator=(const tuple& u);-2-
[…]RequiresRemarks: This operator shall be defined as deleted unlessis_copy_assignable_v<Ti>
istrue
for alli
.tuple& operator=(tuple&& u) noexcept(see below);-5- Remark: The expression inside
noexcept
is equivalent to the logical AND of the following expressions:is_nothrow_move_assignable_v<Ti>where
-6-Ti
is theith
type inTypes
.RequiresRemarks: This operator shall be defined as deleted unlessis_move_assignable_v<Ti>
istrue
for alli
. […]template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);-9-
[…]RequiresRemarks: This operator shall not participate in overload resolution unlesssizeof...(Types) == sizeof...(UTypes)
andis_assignable_v<Ti&, const Ui&>
istrue
for alli
.template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);-12-
[…]RequiresRemarks: This operator shall not participate in overload resolution unlessis_assignable_v<Ti&, Ui&&> == true
for alli
.andsizeof...(Types) == sizeof...(UTypes)
.template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);-15-
[…]RequiresRemarks: This operator shall not participate in overload resolution unlesssizeof...(Types) == 2
.andis_assignable_v<T0&, const U1&>
istrue
for the first typeT0
inTypes
andis_assignable_v<T1&, const U2&>
istrue
for the second typeT1
inTypes
.template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);-18-
RequiresRemarks: This operator shall not participate in overload resolution unlesssizeof...(Types) == 2
.andis_assignable_v<T0&, U1&&>
istrue
for the first typeT0
inTypes
andis_assignable_v<T1&, U2&&>
istrue
for the second typeT1
inTypes
.