Condividi tramite


Elementi Lvalue e Rvalue (C++)

Ogni espressione C++ ha un tipo e appartiene a una categoria di valori. Le categorie di valori sono la base per le regole che i compilatori devono seguire durante la creazione, la copia e lo spostamento di oggetti temporanei durante la valutazione delle espressioni.

Lo standard C++17 definisce le categorie di valori di espressione come indicato di seguito:

  • Un glvalue è un'espressione la cui valutazione determina l'identità di un oggetto, di un campo di bit o di una funzione.
  • Un prvalue è un'espressione la cui valutazione inizializza un oggetto o un campo di bit oppure calcola il valore dell'operando di un operatore, come specificato dal contesto in cui viene visualizzato.
  • Un valore xvalue è un glvalue che denota un oggetto o un campo di bit le cui risorse possono essere riutilizzate (in genere perché è vicino alla fine della durata). Esempio: alcuni tipi di espressioni che coinvolgono riferimenti rvalue (8.3.2) producono xvalue, ad esempio una chiamata a una funzione il cui tipo restituito è un riferimento rvalue o un cast a un tipo di riferimento rvalue.
  • Un lvalue è un glvalue che non è un valore xvalue.
  • Un rvalue è un prvalue o un valore xvalue.

Il diagramma seguente illustra le relazioni tra le categorie:

Diagram of C++ expression value categories.

Il diagramma inizia con un'espressione con etichetta box, che ha due elementi figlio: glvalue e rvalue. glvalue ha due figli: lvalue e xvalue. rvalue ha due figli: prvalue e xvalue; xvalue è anche un elemento figlio di glvalue.

Un lvalue ha un indirizzo a cui il programma può accedere. Esempi di espressioni lvalue includono nomi di variabili, tra cui const variabili, elementi di matrice, chiamate di funzione che restituiscono un riferimento lvalue, campi bit, unioni e membri di classe.

Un'espressione prvalue non ha un indirizzo accessibile dal programma. Esempi di espressioni prvalue includono valori letterali, chiamate di funzione che restituiscono un tipo non di riferimento e oggetti temporanei creati durante la valutazione dell'espressione, ma accessibili solo dal compilatore.

Un'espressione xvalue ha un indirizzo che non è più accessibile dal programma, ma può essere usato per inizializzare un riferimento rvalue, che fornisce l'accesso all'espressione. Ad esempio, le chiamate di funzione che restituiscono un riferimento rvalue e l'indice di matrice, il membro e il puntatore alle espressioni membro in cui la matrice o l'oggetto è un riferimento rvalue.

Esempio

Nell'esempio seguente vengono illustrati diversi utilizzi corretti e non corretti di lvalue e rvalue:

// 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
}

Nota

Gli esempi contenuti in questo argomento illustrano utilizzi corretti e non corretti riferiti ai casi in cui gli operatori non sono sottoposti a overload. Eseguendo l'overload degli operatori, è possibile rendere un'espressione come j * 4 un lvalue.

I termini lvalue e rvalue vengono spesso usati quando si fa riferimento ai riferimenti agli oggetti. Per altre informazioni sui riferimenti, vedere Dichiaratore di riferimento Lvalue: & and Rvalue Reference Declarator: &&.

Vedi anche

Concetti di base
Dichiaratore di riferimento lvalue: &
Dichiaratore di riferimento rvalue: &&