Issue 809: std::swap should be overloaded for array types (original) (raw)
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: 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 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 void swap(W& x, W& 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!
Wstd::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]:
-
TisSwappableifTis 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
Tshall beSwappable.Effects:
swap_ranges(a, a + N, b);