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

NAME
     std::move_if_noexcept - std::move_if_noexcept

Synopsis
	Defined in header <utility>
	template< class T >

	typename std::conditional<
	    !std::is_nothrow_move_constructible<T>::value		      &&
     (since C++11)
	std::is_copy_constructible<T>::value,
     (until C++14)
	    const T&,
	    T&&

	>::type move_if_noexcept( T& x ) noexcept;
	template< class T >

	constexpr typename std::conditional<
	    !std::is_nothrow_move_constructible<T>::value &&
	std::is_copy_constructible<T>::value,
     (since C++14)
	    const T&,
	    T&&

	>::type move_if_noexcept( T& x ) noexcept;

	std::move_if_noexcept obtains an rvalue reference to its argument if its
     move
	constructor does not throw exceptions or if there is no copy constructor
     (move-only
	type), otherwise obtains an lvalue reference to its argument. It is typ-
     ically used
	to combine move semantics with strong exception guarantee.

Parameters
	x - the object to be moved or copied

Return value
	std::move(x) or x, depending on exception guarantees.

Complexity
	Constant.

Notes
	This is used, for example, by std::vector::resize, which may have to al-
     locate new
	storage and then move or copy elements from old storage to new	storage.
     If an
	exception  occurs  during  this  operation,  std::vector::resize  undoes
     everything it did
	to this point, which is only possible if std::move_if_noexcept was  used
     to decide
	whether  to use move construction or copy construction (unless copy con-
     structor is
	not available, in which case move constructor is used either way and the
     strong
	exception guarantee may be waived).

Example
     // Run this code

      #include <iostream>
      #include <utility>

      struct Bad
      {
	  Bad() {}
	  Bad(Bad&&) // may throw
	  {
	      std::cout << "Throwing move constructor called\n";
	  }
	  Bad(const Bad&) // may throw as well
	  {
	      std::cout << "Throwing copy constructor called\n";
	  }
      };

      struct Good
      {
	  Good() {}
	  Good(Good&&) noexcept // will NOT throw
	  {
	      std::cout << "Non-throwing move constructor called\n";
	  }
	  Good(const Good&) noexcept // will NOT throw
	  {
	      std::cout << "Non-throwing copy constructor called\n";
	  }
      };

      int main()
      {
	  Good g;
	  Bad b;
	  [[maybe_unused]] Good g2 = std::move_if_noexcept(g);
	  [[maybe_unused]] Bad b2 = std::move_if_noexcept(b);
      }

Output:
      Non-throwing move constructor called
      Throwing copy constructor called

See also
	forward forwards a function argument
	(C++11) (function template)
	move	obtains an rvalue reference
	(C++11) (function template)

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

home | help