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

NAME
     std::move - std::move

Synopsis
	Defined in header <utility>
	template<		    class		    T		       >
     (since C++11)
	typename std::remove_reference<T>::type&& move( T&& t ) noexcept;   (un-
     til C++14)
	template<		    class		    T		       >
     (since C++14)
	constexpr std::remove_reference_t<T>&& move( T&& t ) noexcept;

	std::move is used to indicate that an object t may be "moved from", i.e.
     allowing
	the efficient transfer of resources from t to another object.

	In particular, std::move produces an xvalue expression	that  identifies
     its argument
	t.  It	is  exactly  equivalent  to a static_cast to an rvalue reference
     type.

Parameters
	t - the object to be moved

Return value
	static_cast<typename std::remove_reference<T>::type&&>(t)

Notes
	The functions that accept rvalue reference  parameters	(including  move
     constructors,
	move assignment operators, and regular member functions such as
	std::vector::push_back)  are  selected,  by  overload  resolution,  when
     called with
	rvalue arguments (either prvalues such as a temporary object or  xvalues
     such as the
	one produced by std::move). If the argument identifies a resource-owning
     object,
	these  overloads  have	the option, but aren't required, to move any re-
     sources held by
	the argument. For example, a move constructor of  a  linked  list  might
     copy the
	pointer  to  the  head of the list and store nullptr in the argument in-
     stead of
	allocating and copying individual nodes.

	Names of rvalue reference variables are lvalues and have to be converted
     to xvalues
	to be bound to the function overloads that accept rvalue reference para-
     meters, which
	is why move constructors and move  assignment  operators  typically  use
     std::move:

      // Simple move constructor
      A(A&&  arg) : member(std::move(arg.member)) // the expression "arg.member"
     is lvalue
      {}

      // Simple move assignment operator
      A& operator=(A&& other)
      {
	  member = std::move(other.member);
	  return *this;
      }

	One exception is when the type of the function parameter is a forwarding
     reference
	(which looks like an rvalue reference to type  template  parameter),  in
     which case
	std::forward is used instead.

	Unless	otherwise specified, all standard library objects that have been
     moved from
	are placed in a "valid but  unspecified  state",  meaning  the	object's
     class invariants
	hold  (so functions without preconditions, such as the assignment opera-
     tor, can be
	safely used on the object after it was moved from):

      std::vector<std::string> v;
      std::string str = "example";
      v.push_back(std::move(str)); // str is now valid but unspecified
      str.back(); // undefined behavior if size() == 0: back() has  a  precondi-
     tion !empty()
      if (!str.empty())
	  str.back(); // OK, empty() has no precondition and back() precondition
     is met

      str.clear(); // OK, clear() has no preconditions

	Also,  the  standard  library functions called with xvalue arguments may
     assume the
	argument is the only reference to the object; if it was constructed from
     an lvalue
	with std::move, no aliasing checks are made. However,  self-move-assign-
     ment of
	standard library types is guaranteed to place the object in a valid (but
     usually
	unspecified) state:

      std::vector<int> v = {2, 3, 3};
      v = std::move(v); // the value of v is unspecified

Example
     // Run this code

      #include <iomanip>
      #include <iostream>
      #include <string>
      #include <utility>
      #include <vector>

      int main()
      {
	  std::string str = "Salut";
	  std::vector<std::string> v;

	  // uses the push_back(const T&) overload, which means
	  // we'll incur the cost of copying str
	  v.push_back(str);
	  std::cout << "After copy, str is " << std::quoted(str) << '\n';

	  // uses the rvalue reference push_back(T&&) overload,
	  // which means no strings will be copied; instead, the contents
	  // of str will be moved into the vector. This is less
	  // expensive, but also means str might now be empty.
	  v.push_back(std::move(str));
	  std::cout << "After move, str is " << std::quoted(str) << '\n';

	  std::cout << "The contents of the vector are {" << std::quoted(v[0])
		    << ", " << std::quoted(v[1]) << "}\n";
      }

Possible output:
      After copy, str is "Salut"
      After move, str is ""
      The contents of the vector are {"Salut", "Salut"}

See also
	forward 	 forwards a function argument
	(C++11) 	 (function template)
	move_if_noexcept  obtains  an  rvalue  reference if the move constructor
     does not throw
	(C++11) 	 (function template)
	move		 moves a range of elements to a new location
	(C++11) 	 (function template)

http://cppreference.com 	   2024.06.10			    std::move(3)

home | help