While implementing a custom tuple (here), I found there is a wired swap() function that takes const parameters (cppreference):
template< class... Types >
constexpr void swap( const std::tuple<Types...>& lhs,
const std::tuple<Types...>& rhs ) noexcept(/* see below */);
and a const-qualified swap() member function (cppreference):
constexpr void swap( const tuple& other ) noexcept(/* see below */) const;
const means the object is read-only, but to swap two objects, it has to modify the objects, which violates the const-ness.
So, What's the purpose of const swap() function?
This was introduced in the "zip" proposal P2321 originally described in "A Plan for C++23 Ranges" P2214.
P2321
swap for const tuple and const pair. Once tuples of references are made const-assignable, the default std::swap can be called for const tuples of references. However, that triple-move swap does the wrong thing:
int i = 1, j = 2; const auto t1 = std::tie(i), t2 = std::tie(j); // If std::swap(t1, t2); called the default triple-move std::swap then // this would do auto tmp = std::move(t1); t1 = std::move(t2); t2 = std::move(tmp); // i == 2, j == 2This paper therefore proposes adding overloads of swap for const tuples and pairs to correctly perform element-wise swap.
P2214 explains why const assignability is needed for the implementation of zip. It stems from assignment operators not being ref qualified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With