Partager via


Lvalues et Rvalues (C++)

Chaque expression C++ a un type et appartient à une catégorie de valeur. Les catégories de valeurs sont la base des règles que les compilateurs doivent suivre lors de la création, de la copie et du déplacement d’objets temporaires pendant l’évaluation d’expression.

La norme C++17 définit les catégories de valeurs d’expression comme suit :

  • Une glvalue est une expression dont l’évaluation détermine l’identité d’un objet, d’un champ de bits ou d’une fonction.
  • Une prvalue est une expression dont l’évaluation initialise un objet ou un champ de bits, ou calcule la valeur de l’opérande d’un opérateur, comme spécifié par le contexte dans lequel il apparaît.
  • Une valeur xvalue est une glvalue qui désigne un objet ou un champ bit dont les ressources peuvent être réutilisées (généralement parce qu’elle est proche de la fin de sa durée de vie). Exemple : certains types d’expressions impliquant des références rvalue (8.3.2) produisent des valeurs xvalues, telles qu’un appel à une fonction dont le type de retour est une référence rvalue ou un cast en type de référence rvalue.
  • Une lvalue est une glvalue qui n’est pas une valeur xvalue.
  • Une valeur rvalue est une valeur prvalue ou une valeur xvalue.

Le diagramme suivant illustre les relations entre les catégories :

Diagram of C++ expression value categories.

Le diagramme commence par une expression étiquetée box, qui a deux enfants : glvalue et rvalue. glvalue a deux enfants : lvalue et xvalue. rvalue a deux enfants : prvalue et xvalue ; xvalue est également un enfant de glvalue.

Une valeur lvalue a une adresse à laquelle votre programme peut accéder. Les exemples d’expressions lvalue incluent des noms de variables, notamment const des variables, des éléments de tableau, des appels de fonction qui retournent une référence lvalue, des champs de bits, des unions et des membres de classe.

Une expression prvalue n’a aucune adresse accessible par votre programme. Les exemples d’expressions prvalue incluent des littéraux, des appels de fonction qui retournent un type non-inférence et des objets temporaires créés lors de l’évaluation d’expression, mais accessibles uniquement par le compilateur.

Une expression xvalue a une adresse qui n’est plus accessible par votre programme, mais qui peut être utilisée pour initialiser une référence rvalue, qui fournit l’accès à l’expression. Par exemple, les appels de fonction qui retournent une référence rvalue et l’indice de tableau, le membre et le pointeur vers les expressions membres où le tableau ou l’objet est une référence rvalue.

Exemple

L'exemple suivant illustre plusieurs utilisations correctes et incorrectes des valeurs lvalues et des rvalues :

// lvalues_and_rvalues2.cpp
int main()
{
    int i, j, *p;

    // Correct usage: the variable i is an lvalue and the literal 7 is a prvalue.
    i = 7;

    // Incorrect usage: The left operand must be an lvalue (C2106).`j * 4` is a prvalue.
    7 = i; // C2106
    j * 4 = 7; // C2106

    // Correct usage: the dereferenced pointer is an lvalue.
    *p = i;

    // Correct usage: the conditional operator returns an lvalue.
    ((i < 3) ? i : j) = 7;

    // Incorrect usage: the constant ci is a non-modifiable lvalue (C3892).
    const int ci = 7;
    ci = 9; // C3892
}

Remarque

Les exemples de cette rubrique illustrent une utilisation correcte et incorrecte lorsque les opérateurs ne sont pas surchargés. En surchargeant les opérateurs, vous pouvez faire d'une expression telle que j * 4 une lvalue.

Les termes lvalue et rvalue sont souvent utilisés lorsque vous faites référence à des références d’objet. Pour plus d’informations sur les références, consultez Lvalue Reference Declarator : & and Rvalue Reference Declarator : &>.

Voir aussi

Concepts de base
Déclarateur de référence Lvalue : &
Déclarateur de référence Rvalue : &&