std:: forward
|
Défini dans l'en-tête
<utility>
|
||
| (1) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type & t ) noexcept ; |
(depuis C++11)
(jusqu'à C++14) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > & t ) noexcept ; |
(depuis C++14) | |
| (2) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type && t ) noexcept ; |
(depuis C++11)
(jusqu'à C++14) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > && t ) noexcept ; |
(depuis C++14) | |
Lorsque t est une référence de transfert (un argument de fonction déclaré comme une référence à une valeur r vers un paramètre de modèle de fonction non qualifié cv), cette surcharge transfère l'argument à une autre fonction avec la catégorie de valeur qu'il avait lors du passage à la fonction appelante.
Par exemple, si utilisé dans un wrapper tel que le suivant, le modèle se comporte comme décrit ci-dessous :
template<class T> void wrapper(T&& arg) { // arg est toujours une lvalue foo(std::forward<T>(arg)); // Transfère comme lvalue ou comme rvalue, selon T }
-
Si un appel à
wrapper()passe une rvaluestd::string, alorsTest déduit enstd::string(et nonstd::string&,const std::string&, oustd::string&&), etstd::forwardgarantit qu'une référence rvalue est passée àfoo. -
Si un appel à
wrapper()passe une lvalue conststd::string, alorsTest déduit enconst std::string&, etstd::forwardgarantit qu'une référence lvalue const est passée àfoo. -
Si un appel à
wrapper()passe une lvalue non-conststd::string, alorsTest déduit enstd::string&, etstd::forwardgarantit qu'une référence lvalue non-const est passée àfoo.
Cette surcharge permet de transmettre le résultat d'une expression (tel qu'un appel de fonction), qui peut être une rvalue ou une lvalue, en conservant la catégorie de valeur originale d'un argument de référence de transfert.
Par exemple, si un wrapper n'effectue pas simplement un transfert de son argument, mais appelle une fonction membre sur l'argument, et transmet son résultat :
// wrapper de transformation template<class T> void wrapper(T&& arg) { foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get())); }
où le type de arg peut être
struct Arg { int i = 1; int get() && { return i; } // l'appel à cette surcharge est une rvalue int& get() & { return i; } // l'appel à cette surcharge est une lvalue };
Tenter de transmettre une rvalue en tant que lvalue, par exemple en instanciant la forme (2) avec un type référence lvalue T, constitue une erreur à la compilation.
Table des matières |
Notes
Voir
la déduction d'arguments de template
pour les règles spéciales concernant les références de transfert (
T&&
utilisé comme paramètre de fonction) et
les références de transfert
pour plus de détails.
Paramètres
| t | - | l'objet à transmettre |
Valeur de retour
static_cast < T && > ( t )
Complexité
Constante.
Exemple
Cet exemple démontre le transfert parfait des paramètres vers l'argument du constructeur de la classe
T
. Le transfert parfait des packs de paramètres est également démontré.
#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); }
Sortie :
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
Voir aussi
|
(C++11)
|
convertit l'argument en une xvalue
(modèle de fonction) |
|
(C++11)
|
convertit l'argument en une xvalue si le constructeur de déplacement ne lève pas d'exception
(modèle de fonction) |