Maison > développement back-end > C++ > Comment `std::move()` réalise-t-il la conversion des lvalues ​​en rvalues ​​en C ?

Comment `std::move()` réalise-t-il la conversion des lvalues ​​en rvalues ​​en C ?

Linda Hamilton
Libérer: 2024-11-21 08:14:09
original
551 Les gens l'ont consulté

How does `std::move()` achieve the conversion of lvalues to rvalues in C  ?

Comment std::move transforme-t-il les expressions en valeurs R ?

std::move() facilite la conversion des expressions en valeurs R (à droite références de valeur) pour activer la sémantique de déplacement. Cependant, l'implémentation dans la bibliothèque standard MSVC peut prêter à confusion.

L'implémentation est la suivante :

template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&amp;&amp;
move(_Ty&amp;&amp; _Arg)
{ // forward _Arg as movable
    return ((typename tr1::_Remove_reference<_Ty>::_Type&amp;&amp;)_Arg);
}
Copier après la connexion

Montrons comment cela fonctionne :

Object obj1;
Object obj2 = std::move(obj1); // _Ty&amp;&amp; _Arg binds to obj1
Copier après la connexion

Sur en appelant std::move(), le paramètre de référence _Arg se lie à la lvalue obj1. Cependant, étant donné que la liaison d'une référence rvalue à une lvalue n'est pas directement autorisée, on pourrait s'attendre à ce qu'une conversion en une référence rvalue, telle que (Object&&), soit requise.

Approfondir l'implémentation de std :: Remove_reference clarifie les choses :

template<class _Ty>
struct _Remove_reference
{ // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&amp;>
{ // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&amp;&amp;>
{ // remove rvalue reference
    typedef _Ty _Type;
};
Copier après la connexion

Cette implémentation révèle que Remove_reference transforme T& en T, T&& en T et T&&& en T. Par conséquent, pour notre cas, où obj1 est une lvalue de type Object, la fonction résultante devient :

Object&amp;&amp; move(Object&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}
Copier après la connexion

Pour élaborer davantage :

  • Lorsque move est invoqué avec une rvalue (par exemple, std ::move(Object())), T devient Object et la fonction résultante est :
Object&amp;&amp; move(Object&amp;&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}
Copier après la connexion

Le cast en Object&& est nécessaire car les références rvalue nommées sont traitées comme des lvalues, tandis que la conversion implicite de lvalue en référence rvalue est interdite.

  • Lorsque move est invoqué avec une lvalue, comme dans notre exemple précédent, T devient Object&, et la fonction résultante est :
Object&amp;&amp; move(Object&amp; &amp;&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}
Copier après la connexion

Ici, les règles d'effondrement de référence de C 11 entrent en jeu et permettent l'expression Object& && doit être interprété comme Object&, une référence lvalue, qui peut en effet se lier à des lvalues. Ainsi, la fonction finale transforme son argument en référence rvalue et le renvoie.

En conclusion, std::move() utilise std::remove_reference pour permettre la transformation des lvalues ​​et des rvalues ​​en rvalues, facilitant ainsi le déplacement sémantique en C .

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal