array<const int, 0>
swappable or not?Section: 23.3.3.4 [array.special] Status: Open Submitter: Casey Carter Opened: 2020-10-01 Last modified: 2020-10-04
Priority: 3
View all issues with Open status.
Discussion:
Per 23.3.3.4 [array.special]/1,
std::array
's non-member swap participates in overload resolution
when the array has size 0 or swappable elements.
The effects of non-member swap are "As if by [member swap]",
but member swap's effects are simply
"Equivalent to swap_ranges(begin(), end(), y.begin())"
per 23.3.3.3 [array.members]/4.
In effect, we've gone out of our way to ensure that
is_swappable_v<array<T, 0>>
and swappable<array<T, 0>>
are always true
despite that actually swapping such an array may be ill-formed.
It seems that the wording stops half-way to making
array<T, 0>
swappable regardless of T
.
I personally find that design distasteful
- it seems a gratuitous difference between
array<T, N>
and array<T, 0>
- but I'd prefer a consistent design over the status quo
even if it's the "wrong" design.
[2020-10-02; Issue processing telecon]
Preference for Option B, and successful vote to move to Tentatively Ready. But on the reflector Tim Song pointed out a conflict with 2157 and question the decision. Status to Open instead. Priority set to P3 in line with 2157.
Proposed resolution:
Wording relative to N4861.
This resolution proposes two wording alternatives: Option A makesarray<T, 0>
swappable regardless of T
,
and the clearly superior Option B makes array<T, N>
swappable
only if T
is swappable (i.e., regardless of N
)
removing gratuitous special-case behavior for the N == 0
case.
Option A:
Change 23.3.3.3 [array.members] as follows:
constexpr void swap(array& y) noexcept(N == 0 || is_nothrow_swappable_v<T>);
-4- Effects: If N == 0
, no effects. Otherwise, equivalent Equivalent to swap_ranges(begin(), end(), y.begin())
.
-5- […]
Also remove the now-redundant paragraph four from 23.3.3.5 [array.zero] as follows:
-4- Member functionswap()
shall have a non-throwing exception specification.
Option B:
Change 23.3.3.4 [array.special] as follows:
template<class T, size_t N> constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
-1- Constraints: N == 0
oris_swappable_v<T>
is true
.
Also remove paragraph four from 23.3.3.5 [array.zero] as follows:
-4- Member functionswap()
shall have a non-throwing exception specification.