std:: forward
|
Definiert im Header
<utility>
|
||
| (1) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type & t ) noexcept ; |
(seit C++11)
(bis C++14) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > & t ) noexcept ; |
(seit C++14) | |
| (2) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type && t ) noexcept ; |
(seit C++11)
(bis C++14) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > && t ) noexcept ; |
(seit C++14) | |
Wenn t eine Forwarding Reference (ein Funktionsargument, das als Rvalue-Referenz auf einen cv-unqualifizierten Funktions-Template-Parameter deklariert ist) ist, leitet diese Überladung das Argument an eine andere Funktion mit der Value Category weiter, die es beim Aufruf der Funktion hatte.
Beispielsweise, wenn in einem Wrapper wie dem folgenden verwendet, verhält sich das Template wie unten beschrieben:
template<class T> void wrapper(T&& arg) { // arg ist immer ein Lvalue foo(std::forward<T>(arg)); // Weiterleiten als Lvalue oder Rvalue, abhängig von T }
-
Wenn ein Aufruf von
wrapper()einen Rvaluestd::stringübergibt, dann wirdTzustd::stringabgeleitet (nichtstd::string&,const std::string&, oderstd::string&&), undstd::forwardstellt sicher, dass eine Rvalue-Referenz anfooübergeben wird. -
Wenn ein Aufruf von
wrapper()einen const Lvaluestd::stringübergibt, dann wirdTzuconst std::string&abgeleitet, undstd::forwardstellt sicher, dass eine const Lvalue-Referenz anfooübergeben wird. -
Wenn ein Aufruf von
wrapper()einen nicht-konstanten Lvaluestd::stringübergibt, dann wirdTzustd::string&abgeleitet, undstd::forwardstellt sicher, dass eine nicht-konstante Lvalue-Referenz anfooübergeben wird.
Diese Überladung ermöglicht es, das Ergebnis eines Ausdrucks (wie z.B. eines Funktionsaufrufs), der ein Rvalue oder Lvalue sein kann, mit der ursprünglichen Wertkategorie eines Forwarding-Referenzarguments weiterzuleiten.
Beispielsweise, wenn ein Wrapper nicht einfach sein Argument weiterleitet, sondern eine Memberfunktion auf dem Argument aufruft und deren Ergebnis weiterleitet:
// transformierender Wrapper template<class T> void wrapper(T&& arg) { foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get())); }
wobei der Typ von arg sein kann
struct Arg { int i = 1; int get() && { return i; } // Aufruf dieser Überladung ist Rvalue int& get() & { return i; } // Aufruf dieser Überladung ist Lvalue };
Der Versuch, einen Rvalue als Lvalue weiterzuleiten, beispielsweise durch Instanziierung der Form (2) mit Lvalue-Referenztyp T, ist ein Compilezeitfehler.
Inhaltsverzeichnis |
Hinweise
Siehe
Template-Argument-Deduktion
für die speziellen Regeln hinter Forwarding-References (
T&&
als Funktionsparameter verwendet) und
Forwarding-References
für weitere Details.
Parameter
| t | - | das zu weiterleitende Objekt |
Rückgabewert
static_cast < T && > ( t )
Komplexität
Konstante.
Beispiel
Dieses Beispiel demonstriert das perfekte Weiterleiten der Parameter an das Argument des Konstruktors der Klasse
T
. Zudem wird das perfekte Weiterleiten von Parameterpaketen gezeigt.
#include <iostream> #include <memory> #include <utility> struct A { A(int&& n) { std::cout << "rvalue overload, n=" << n << '\n'; } A(int& n) { std::cout << "lvalue overload, n=" << n << '\n'; } }; class B { public: template<class T1, class T2, class T3> B(T1&& t1, T2&& t2, T3&& t3) : a1_{std::forward<T1>(t1)}, a2_{std::forward<T2>(t2)}, a3_{std::forward<T3>(t3)} {} private: A a1_, a2_, a3_; }; template<class T, class U> std::unique_ptr<T> make_unique1(U&& u) { return std::unique_ptr<T>(new T(std::forward<U>(u))); } template<class T, class... U> std::unique_ptr<T> make_unique2(U&&... u) { return std::unique_ptr<T>(new T(std::forward<U>(u)...)); } auto make_B(auto&&... args) // since C++20 { return B(std::forward<decltype(args)>(args)...); } int main() { auto p1 = make_unique1<A>(2); // rvalue int i = 1; auto p2 = make_unique1<A>(i); // lvalue std::cout << "B\n"; auto t = make_unique2<B>(2, i, 3); std::cout << "make_B\n"; [[maybe_unused]] B b = make_B(4, i, 5); }
Ausgabe:
rvalue overload, n=2 lvalue overload, n=1 B rvalue overload, n=2 lvalue overload, n=1 rvalue overload, n=3 make_B rvalue overload, n=4 lvalue overload, n=1 rvalue overload, n=5
Siehe auch
|
(C++11)
|
wandelt das Argument in einen xvalue um
(Funktions-Template) |
|
(C++11)
|
wandelt das Argument in einen xvalue um, wenn der Move-Konstruktor keine Ausnahme wirft
(Funktions-Template) |