Библиотека предоставляет шаблонные вспомогательные функции, чтобы упростить применение семантики перемещения к lvalue и упростить реализацию функций пересылки. Все функции, указанные в этом подпункте, являются signal-safe ( ).[csignal.syn]
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Remarks: Если вторая форма создается со ссылочным типом lvalue, программа имеет неправильный формат.
[ Example:
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 }
При первом вызове factory, A1 выводится как int, поэтому 2 передается Aконструктору как rvalue. Во втором вызове factory, A1 выводится как int&, поэтому i передается Aконструктору как lvalue. В обоих случаях A2 выводится как double, поэтому 1.414 передается Aконструктору как rvalue. ] — end example
template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
[ Example:
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> sp1 = factory<A>(std::move(a)); // “a” binds to A(A&&) }
При первом вызове factory, A1 выводится как A&, поэтому a передается как неконстантное lvalue. Это связывается с конструктором A(const A&), который копирует значение из a. Во втором вызове factory, из - за вызова std::move(a), A1 выводится в виде A, так a пересылается как RValue. Это связывается с конструктором A(A&&), который перемещает значение из 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;