Lvalores e rvalores

As expressões podem ser categorizadas em uma das seguintes categorias de valor:

Valor L

Uma expressão pode aparecer no lado esquerdo de uma expressão de designação se a expressão não forconstqualificado.

""Valor X

Uma referência de rvalue que é para expirar.

""(Valor Pr) rvalue

""Uma expressão não xvalue que aparece apenas no lado direito de uma expressão de atribuição.

Rvalores incluem tanto xvalores e prvalores. Lvalores e xvalores podem ser referidos como glvalores.

Notas:

  • Os rvalores de classe ""(prvalue) podem ser cv-qualificados, mas os rvalores não de classe ""(prvalue) não podem ser cv-qualificados.
  • Lvalores ""e xvalores podem ser de tipos incompletos, mas os rvalores de ""(prvalue) devem ser de tipos completos ouvoidtipo compatíveis.
Um objeto é uma região de armazenamento que pode ser examinada e armazenada em. Um lvalue ou ""xvalueé uma expressão que se refere a tal objeto. Um lvalue não permite necessariamente a modificação do objeto que designa. Por exemplo, um objeto const é um lvalue que não pode ser modificado. O termo lvalue modificável é usado para enfatizar que o lvalue permite que o objeto designado seja alterado, assim como examinado. Os seguintes tipos de objeto são lvalores, mas não lvalores modificáveis:
  • Um tipo de matriz
  • Um tipo incompleto
  • Um tipo const-qualificado
  • Uma estrutura ou tipo de união com um de seus membros qualificados como um tipo const
Como esses lvalores não são modificáveis, eles não podem aparecer no lado esquerdo de uma instrução de designação.

O termo rvalue refere-se a um valor de dados que é armazenado em algum endereço na memória. Um rvalue é uma expressão que não pode ter um valor atribuído a ele. Tanto uma constante literal quanto uma variável podem servir como um rvalor. Quando um lvalue aparece em um contexto que requer um rvalue, o lvalue é implicitamente convertido em um rvalue. O inverso, no entanto, não é verdadeiro: um rvalue não pode ser convertido em um lvalue. Rvalores sempre possuem tipos completos ou o tipo void.

C apenas C define um designator de função como uma expressão que possui tipo de função. Um designador de função é distinto de um tipo de objeto ou de um lvalue. Pode ser o nome de uma função ou o resultado de dereferenciar um ponteiro de função. A linguagem C também se diferencia entre o seu tratamento de um ponteiro de função e um ponteiro de objetos.

C++ Por outro lado, em C + +, uma chamada de função que retorna uma referência é um lvalue. Caso contrário, uma chamada de função é uma expressão rvalue. Em C + +, toda expressão produz um lvalue, um xvalor "", um rvalue de ""(prvalue), ou nenhum valor.

Em ambos C e C + +, certos operadores requerem lvalores para alguns de seus operandos. A tabela abaixo lista essas operadoras e restrições adicionais sobre o seu uso.
Operador Requisito
& (unário) O operando deve ser um lvalue.
++ -- O operando deve ser um lvalue. Isso se aplica a formulários de prefixo e de pós-correção.
= += -= *= %= <<= >>= &= ^= |= O operário esquerdo deve ser um lvalia.

Por exemplo, todos os operadores de designação avaliam o seu operando direito e atribuem esse valor à sua operante esquerda. O operário esquerdo deve ser um lvalue modificável ou uma referência a um objeto modificável.

O operador de endereço (&) requer um lvalue como operado enquanto que o incremento (++) e os operadores de decremento (--) requerem um lvalue modificável como um operando. O exemplo a seguir mostra expressões e seus lvalores correspondentes.
Expressão Lvalia
x = 42 x
*ptr = newvalue *ptr
a++ a
C++ int& f() A chamada de função para f()

C++ Início de C++11 apenas.

As expressões a seguir são xvalores:

  • O resultado de ligar para uma função cujo tipo de retorno é de um tipo de referência de rvalor
  • Um elenco para uma referência de rvalue
  • Um membro de dados não estático de um tipo não referência acessado através de uma expressão xvalue
  • Um ponteiro para a expressão de acesso a membro em que o primeiro opere é uma expressão xvalue e o segundo operando é de um ponteiro para o tipo membro

Consulte o seguinte exemplo:

int a;
int&& b= static_cast<int&&>(a);

struct str{
   int c;
};

int&& f(){
   int&& var =1;
   return var;
}

str&& g();
int&& rc = g().c;

Neste exemplo, A inicializadora para referência de rvaluebé um xvalue porque é um resultado de um molde para uma referência de rvalue. Uma chamada para a funçãof()produz um xvalue porque o tipo de retorno desta função é doint&&tipo. O inicializador para referência de rvaluercé um xvalue porque é uma expressão que acessa um membro de dados não estático não referênciacatravés de uma expressão xvalue.

C++ Fim de C++11 apenas.

Informações relacionadas