Title
Is array<const int, 0> swappable or not?
Status
open
Section
[array.special]
Submitter
Casey Carter

Created on 2020-10-01.00:00:00 last changed 50 months ago

Messages

Date: 2020-10-02.18:55:53

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 [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 [array.zero] as follows:

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

Option B:

  1. Change [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 [array.zero] as follows:

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

Date: 2020-10-15.00:00:00

[ 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.

Date: 2020-10-01.00:00:00

Per [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 [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.

History
Date User Action Args
2020-10-02 18:55:53adminsetmessages: + msg11503
2020-10-02 18:55:53adminsetstatus: new -> open
2020-10-01 12:57:34adminsetmessages: + msg11494
2020-10-01 00:00:00admincreate