Maison > développement back-end > C++ > le corps du texte

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
453 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!

source:php.cn
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