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

### 809. `std::swap` should be overloaded for array types

Section: 25.7.3 [alg.swap] Status: CD1 Submitter: Niels Dekker Opened: 2008-02-28 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [alg.swap].

View all issues with CD1 status.

Discussion:

For the sake of generic programming, the header `<algorithm>` should provide an overload of `std::swap` for array types:

    template<class T, size_t N> void swap(T (&a)[N], T (&b)[N]);

It became apparent to me that this overload is missing, when I considered how to write a swap function for a generic wrapper class template. (Actually I was thinking of Boost's value_initialized.) Please look at the following template, `W`, and suppose that is intended to be a very generic wrapper:

    template<class T> class W {
    public:
      T data;
    };

Clearly `W<T>` is CopyConstructible and CopyAssignable, and therefore Swappable, whenever `T` is CopyConstructible and CopyAssignable. Moreover, `W<T>` is also Swappable when `T` is an array type whose element type is CopyConstructible and CopyAssignable. Still it is recommended to add a custom swap function template to such a class template, for the sake of efficiency and exception safety. (E.g., Scott Meyers, Effective C++, Third Edition, item 25: Consider support for a non-throwing swap.) This function template is typically written as follows:

    template<class T> void swap(W<T>& x, W<T>& y) {
      using std::swap;
      swap(x.data, y.data);
    }

Unfortunately, this will introduce an undesirable inconsistency, when `T` is an array. For instance, `W<std::string[8]>` is Swappable, but the current Standard does not allow calling the custom swap function that was especially written for `W`!

    W<std::string[8]> w1, w2;  // Two objects of a Swappable type.
    std::swap(w1, w2);  // Well-defined, but inefficient.
    using std::swap;
    swap(w1, w2);  // Ill-formed, just because ADL finds W's swap function!!!

`W`'s `swap` function would try to call `std::swap` for an array, `std::string[8]`, which is not supported by the Standard Library. This issue is easily solved by providing an overload of `std::swap` for array types. This swap function should be implemented in terms of swapping the elements of the arrays, so that it would be non-throwing for arrays whose element types have a non-throwing swap.

Note that such an overload of `std::swap` should also support multi-dimensional arrays. Fortunately that isn't really an issue, because it would do so automatically, by means of recursion.

For your information, there was a discussion on this issue at comp.lang.c++.moderated: [Standard Library] Shouldn't std::swap be overloaded for C-style arrays?

Proposed resolution:

Add an extra condition to the definition of Swappable requirements [swappable] in 16.4.4.2 [utility.arg.requirements]:

> - `T` is `Swappable` if `T` is an array type whose element type is `Swappable`.

Add the following to 25.7.3 [alg.swap]:

>     template<class T, size_t N> void swap(T (&a)[N], T (&b)[N]);

> > Requires: Type `T` shall be `Swappable`.

> > Effects: `swap_ranges(a, a + N, b);`