std::swap vs std::exchange vs swap operator

Viewed 18481

An implementation of std::swap might look like this:

template <class T> void swap (T& a, T& b)
{
  T c(std::move(a)); a=std::move(b); b=std::move(c);
}
template <class T, size_t N> void swap (T (&a)[N], T (&b)[N])
{
  for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}

An implementation std::exchange n3668 might look like this:

 template< typename T, typename U = T >
   T exchange( T & obj, U && new_val )
   {
     T old_val = std::move(obj);
     obj = std::forward<U>(new_val);
     return old_val;
   }

It says:

For primitive types, this is equivalent to the obvious implementation, while for more complex types, this definition

  • Avoids copying the old value when that type defines a move constructor
  • Accepts any type as the new value, taking advantage of any converting assignment operator
  • Avoids copying the new value if it's a temporary or moved.

I chose the name for symmetry with atomic_exchange, since they behave the same except for this function not being atomic.

n3746 also proposes a built-in swap operator that looks like this:

inline C& C::operator :=: (C&& y) &  { see below; return *this; } 
inline C& C::operator :=: (C& y)  &  { return *this :=: std::move(y); }

From what I gather, the proposals would like all three of these options to live side by side, rather than replacing each other. Why is it necessary to have three different ways to swap objects?

2 Answers
Related