20 General utilities library [utilities]

20.2 Utility components [utility]

20.2.4 Forward/move helpers [forward]

The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions.
All functions specified in this subclause are signal-safe.
template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Mandates: For the second overload, is_­lvalue_­reference_­v<T> is false.
Returns: static_­cast<T&&>(t).
[Example 1: template<class T, class A1, class A2> shared_ptr<T> factory(A1&& a1, A2&& a2) { return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2))); } struct A { A(int&, const double&); }; void g() { shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int& int i = 2; shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK }
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an rvalue.
In the second call to factory, A1 is deduced as int&, so i is forwarded to A's constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.414 is forwarded to A's constructor as an rvalue.
— end example]
template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
Returns: static_­cast<remove_­reference_­t<T>&&>(t).
[Example 2: template<class T, class A1> shared_ptr<T> factory(A1&& a1) { return shared_ptr<T>(new T(std::forward<A1>(a1))); } struct A { A(); A(const A&); // copies from lvalues A(A&&); // moves from rvalues }; void g() { A a; shared_ptr<A> sp1 = factory<A>(a); // “a” binds to A(const A&) shared_ptr<A> sp2 = factory<A>(std::move(a)); // “a” binds to A(A&&) }
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue.
This binds to the constructor A(const A&), which copies the value from a.
In the second call to factory, because of the call std​::​move(a), A1 is deduced as A, so a is forwarded as an rvalue.
This binds to the constructor A(A&&), which moves the value from a.
— end example]
template<class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;
Returns: std​::​move(x).