This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Open status.

### 3488. Is `array<const int, 0>` swappable or not?

Section: 22.3.7.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 22.3.7.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 22.3.7.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 makes `array<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:

1. Change 22.3.7.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- […]

2. Also remove the now-redundant paragraph four from 22.3.7.5 [array.zero] as follows:

   > -4- Member function `swap()` shall have a non-throwing exception specification.

Option B:

1. Change 22.3.7.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` or `is_swappable_v<T>` is `true`.

2. Also remove paragraph four from 22.3.7.5 [array.zero] as follows:

   > -4- Member function `swap()` shall have a non-throwing exception specification.