Search code examples
c++stdtuple

What's the purpose of const swap() function?


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?


Solution

  • 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 == 2
      

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