C++
Perfekte Weiterleitung
Suche…
Bemerkungen
Eine einwandfreie Weiterleitung erfordert Weiterleitungsreferenzen , um die Ref-Qualifier der Argumente zu erhalten. Solche Verweise erscheinen nur in einem abgeleiteten Kontext . Das ist:
template<class T>
void f(T&& x) // x is a forwarding reference, because T is deduced from a call to f()
{
g(std::forward<T>(x)); // g() will receive an lvalue or an rvalue, depending on x
}
Folgendes beinhaltet keine perfekte Weiterleitung, da T
nicht vom Konstruktoraufruf abgeleitet wird:
template<class T>
struct a
{
a(T&& x); // x is a rvalue reference, not a forwarding reference
};
In C ++ 17 können Klassenvorlagenargumente abgezogen werden. Der Konstruktor von "a" im obigen Beispiel wird Benutzer einer Weiterleitungsreferenz
a example1(1);
// same as a<int> example1(1);
int x = 1;
a example2(x);
// same as a<int&> example2(x);
Werksfunktionen
Angenommen, wir möchten eine Factory-Funktion schreiben, die eine beliebige Liste von Argumenten akzeptiert und diese Argumente unverändert an eine andere Funktion übergibt. Ein Beispiel für eine solche Funktion ist make_unique
, mit der eine neue Instanz von T
sicher erstellt und ein unique_ptr<T>
, das die Instanz besitzt.
Die Sprachregeln für Variadic-Templates und -Referenzreferenzen ermöglichen das Schreiben einer solchen Funktion.
template<class T, class... A>
unique_ptr<T> make_unique(A&&... args)
{
return unique_ptr<T>(new T(std::forward<A>(args)...));
}
Die Verwendung von Ellipsen ...
gibt ein Parameterpaket an, das eine beliebige Anzahl von Typen darstellt. Der Compiler erweitert dieses Parameterpaket auf die richtige Anzahl von Argumenten an der Aufrufstelle. Diese Argumente werden dann mit std::forward
Konstruktor von T
. Diese Funktion ist erforderlich, um die Ref-Qualifier der Argumente zu erhalten.
struct foo
{
foo() {}
foo(const foo&) {} // copy constructor
foo(foo&&) {} // copy constructor
foo(int, int, int) {}
};
foo f;
auto p1 = make_unique<foo>(f); // calls foo::foo(const foo&)
auto p2 = make_unique<foo>(std::move(f)); // calls foo::foo(foo&&)
auto p3 = make_unique<foo>(1, 2, 3);