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.
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
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 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.
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.
| 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.
&) 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 |
int& f() |
A chamada de função para f() |
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.
Fim de C++11 apenas.