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.
std::swap
should be overloaded for array typesSection: 26.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
isSwappable
ifT
is an array type whose element type isSwappable
.
Add the following to 26.7.3 [alg.swap]:
template<class T, size_t N> void swap(T (&a)[N], T (&b)[N]);Requires: Type
T
shall beSwappable
.Effects:
swap_ranges(a, a + N, b);