Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::exchange(3)	      C++ Standard Libary	      std::exchange(3)

NAME
       std::exchange - std::exchange

Synopsis
	  Defined in header <utility>
	  template<	  class	     T,	     class	U      =      T	     >
       (since C++14)
	  T	 exchange(	T&	obj,	  U&&	    new_value	    );
       (until C++20)
	  template<	  class	     T,	     class	U      =      T	     >
       (since C++20)
	  constexpr    T    exchange(	 T&    obj,    U&&    new_value	    );
       (until C++23)
	  template< class T, class U = T >
	  constexpr  T exchange( T& obj, U&& new_value ) noexcept(/* see below
       (since C++23)
	  */);

	  Replaces the value of	obj with new_value and returns the  old	 value
       of obj.

Parameters
	  obj			 -		object whose value to replace
	  new_value		 -		the value to assign to obj

Type requirements
	  -
	  T  must meet the requirements	of MoveConstructible. Also, it must be
       possible	to
	  move-assign objects of type U	to objects of type T

Return value
	  The old value	of obj

Exceptions
	  (none)				     (until C++23)
	  noexcept specification:
	  noexcept(

	  std::is_nothrow_move_constructible_v<T> && (since C++23)
	  std::is_nothrow_assignable_v<T&, U>

	  )

Possible implementation
	  template<class T, class U = T>
	  constexpr // since C++20
	  T exchange(T&	obj, U&& new_value)
	      noexcept(	// since C++23
		  std::is_nothrow_move_constructible<T>::value &&
		  std::is_nothrow_assignable<T&, U>::value
	      )
	  {
	      T	old_value = std::move(obj);
	      obj = std::forward<U>(new_value);
	      return old_value;
	  }

Notes
	  The std::exchange can	be used	when implementing move assignment  op-
       erators and move
	  constructors:

	struct S
	{
	  int n;

	  S(S&&	other) noexcept	: n{std::exchange(other.n, 0)}
	  {}

	  S& operator=(S&& other) noexcept
	  {
	    if(this != &other)
		n  =  std::exchange(other.n, 0); // move n, while leaving zero
       in other.n
	    return *this;
	  }
	};

	  Feature-test macro: __cpp_lib_exchange_function

Example
       // Run this code

	#include <iostream>
	#include <utility>
	#include <vector>
	#include <iterator>

	class stream
	{
	  public:

	   using flags_type = int;

	  public:

	    flags_type flags() const
	    { return flags_; }

	    // Replaces	flags_ by newf,	and returns the	old value.
	    flags_type flags(flags_type	newf)
	    { return std::exchange(flags_, newf); }

	  private:

	    flags_type flags_ =	0;
	};

	void f() { std::cout <<	"f()"; }

	int main()
	{
	   stream s;

	   std::cout <<	s.flags() << '\n';
	   std::cout <<	s.flags(12) << '\n';
	   std::cout <<	s.flags() << "\n\n";

	   std::vector<int> v;

	   // Since the	second template	parameter has a	default	value,	it  is
       possible
	   // to use a braced-init-list	as second argument. The	expression be-
       low
	   // is equivalent to std::exchange(v,	std::vector<int>{1,2,3,4});

	   std::exchange(v, {1,2,3,4});

	   std::copy(begin(v),end(v),  std::ostream_iterator<int>(std::cout,",
       "));

	   std::cout <<	"\n\n";

	   void	(*fun)();

	   // the default value	of template parameter also makes  possible  to
       use a
	   //  normal  function	 as  second  argument. The expression below is
       equivalent to
	   // std::exchange(fun, static_cast<void(*)()>(f))
	   std::exchange(fun,f);
	   fun();

	   std::cout <<	"\n\nFibonacci sequence: ";
	   for (int a{0}, b{1};	a < 100; a = std::exchange(b, a	+ b))
	       std::cout << a << ", ";
	   std::cout <<	"...\n";
	}

Output:
	0
	0
	12

	1, 2, 3, 4,

	f()

	Fibonacci sequence: 0, 1, 1, 2,	3, 5, 8, 13, 21, 34, 55, 89, ...

See also
	  swap			   swaps the values of two objects
				   (function template)
	  atomic_exchange	   atomically replaces the value of the	atomic
       object with
	  atomic_exchange_explicit non-atomic argument	and  returns  the  old
       value of	the atomic
	  (C++11)		   (function template)
	  (C++11)

http://cppreference.com		  2022.07.31		      std::exchange(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::exchange&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help