J’ai vu cela ici : constructeur de déplacer l’appel constructeur de classe de base de déplacer
Quelqu'un pourrait m’expliquer :
- la différence entre
et
, de préférence avec des exemples de code ? - Comment penser facilement et quand utiliser qui
J’ai vu cela ici : constructeur de déplacer l’appel constructeur de classe de base de déplacer
Quelqu'un pourrait m’expliquer :
et
, de préférence avec des exemples de code ?std::move
prend un objet et permet de les traiter de manière temporaire (une rvalue). Bien qu'il n'est pas d'une sémantique de l'exigence, généralement une fonction acceptant une référence à une rvalue invalidera. Quand vous voyez std::move
, cela indique que la valeur de l'objet ne doit pas être utilisé par la suite, mais vous pouvez toujours affecter une nouvelle valeur et continuer à l'utiliser.
std::forward
a qu'un seul cas d'utilisation: jeter basé sur un modèle paramètre de la fonction (à l'intérieur de la fonction) pour la valeur de la catégorie (lvalue ou rvalue) l'appelant utilisé pour la passer. Cela permet rvalue les arguments passés sur que rvalues, et lvalues être transmis que lvalues, un système appelé "transfert parfait."
Pour illustrer:
void overloaded( int const &arg ) { std::cout << "by lvalue\n"; }
void overloaded( int && arg ) { std::cout << "by rvalue\n"; }
template< typename t >
/* "t &&" with "t" being template param is special, and adjusts "t" to be
(for example) "int &" or non-ref "int" so std::forward knows what to do. */
void forwarding( t && arg ) {
std::cout << "via std::forward: ";
overloaded( std::forward< t >( arg ) );
std::cout << "via std::move: ";
overloaded( std::move( arg ) ); // conceptually this would invalidate arg
std::cout << "by simple passing: ";
overloaded( arg );
}
int main() {
std::cout << "initial caller passes rvalue:\n";
forwarding( 5 );
std::cout << "initial caller passes lvalue:\n";
int x = 5;
forwarding( x );
}
Comme Howard mentionne, il y a aussi des similitudes de ces deux fonctions tout simplement jeté à type de référence. Mais en dehors de ces cas d'utilisation spécifiques (qui couvre 99,9% de l'utilité de la référence rvalue jette), vous devez utiliser static_cast
directement et écrire une bonne explication de ce que vous faites.
Les deux std::forward
et std::move
ne sont rien, mais jette.
X x;
std::move(x);
Le jette au-dessus de la lvalue expression x
de type X à une rvalue expression du type X (value pour être exact). move
peut également accepter une rvalue:
std::move(make_X());
et dans ce cas, c'est une identité de fonction: prend une rvalue de type X et qui retourne une valeur r de type X.
Avec std::forward
vous pouvez sélectionner la destination dans une certaine mesure:
X x;
std::forward<Y>(x);
Jette la lvalue expression x
de type X à une expression de type Y. Il y a des contraintes sur ce qui Y peut être.
Y peut être accessible de Base de X, ou une référence à une Base de X. Y X, ou une référence à X. On ne peut pas jeté cv-qualificatifs, avec forward
, mais on peut ajouter cv-qualificatifs. Y ne peut pas être un type qui est simplement convertibles à partir de X, sauf par l'intermédiaire d'un accessibles de la Base de la conversion.
Si Y est une lvalue de référence, le résultat sera une lvalue expression. Si Y n'est pas une lvalue de référence, le résultat sera une rvalue (value pour être précis) de l'expression.
forward
pouvez prendre une rvalue argument que si Y n'est pas une lvalue de référence. Qui est, vous ne peut pas lancer une rvalue à lvalue. C'est pour des raisons de sécurité, car cela entraîne habituellement balançant des références. Mais la coulée d'une rvalue à rvalue est ok et autorisé.
Si vous essayez de spécifier Y à quelque chose qui n'est pas autorisé, l'erreur sera pris au moment de la compilation, pas de temps d'exécution.
std::forward
est utilisé pour transmettre un paramètre exactement la façon dont il a été transmis à une fonction. Tout comme illustré ici:
Lors de l'utilisation de std::avant d'avancer des arguments?
À l'aide de std::move
propose un objet comme une rvalue, pour éventuellement correspondre à un constructeur de déplacement ou une fonction acceptant rvalues. Il le fait pour std::move(x)
même si x
n'est pas une rvalue par lui-même.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.