Pergunta

Tenho codificado em C++ nos últimos anos.Mas há uma questão que não consegui resolver.Quero perguntar, todos os temporários são em C++, rvalues?

Se não, alguém pode me dar um exemplo em que o temporário produzido no código é um valor?

Foi útil?

Solução

Não.

A especificação da linguagem C ++ nunca faz uma afirmação tão direta quanto a que você está perguntando. Não diz em nenhum lugar do padrão de idioma que "todos os objetos temporários são rvalues". Além disso, a questão em si é um pouco de nome impróprio, uma vez que a propriedade de ser um Rvalue no idioma C ++ não é uma propriedade de um objeto, mas uma propriedade de uma expressão (ou seja, uma propriedade de seu resultado). Na verdade, é assim que é definido na especificação do idioma: para diferentes tipos de expressões, diz quando o resultado é um LValue e quando é um Rvalue. Entre outras coisas, isso realmente significa que um objeto temporário pode ser acessado como um RValue e um LValue, dependendo da forma específica de expressão usada para executar o acesso.

Por exemplo, o resultado de literal 2 + 3 A expressão é obviamente um rvalue, um temporário do tipo int. Não podemos aplicar o unário & para isso desde que unário & requer um lvalue como seu operando

&(2 + 3); // ERROR, lvalue required

No entanto, como todos sabemos, uma referência constante pode ser anexada a um objeto temporário, como em

const int &ri = 2 + 3;

Nesse caso, a referência é anexada ao temporário, prolongando a vida útil deste último. Obviamente, uma vez feito, temos acesso a esse mesmo temporário que um lvalue ri, como as referências são sempre lvalues. Por exemplo, podemos aplicar com facilidade e legalmente o unário & para a referência e obter um ponteiro para o temporário

const int *pi = &ri;

com aquele ponteiro permanecendo perfeitamente válido, desde que o temporário persistir.

Outro exemplo óbvio de acesso de LValue a um objeto temporário é quando acessamos um objeto temporário do tipo de classe através de seu this ponteiro. O resultado de *this é um lvalue (como sempre é o caso do resultado de unário * aplicado a um ponteiro de dados), mas isso não altera o fato de que o objeto real pode ser facilmente temporário. Para um determinado tipo de classe T, expressão T() é um rvalue, como explicitamente declarado no padrão de idioma, mas o objeto temporário acessado através *T().get_this() expressão (com a implementação óbvia de T::get_this()) é um lvalue. Ao contrário do exemplo anterior, esse método permite obter imediatamente um LValue não qualificado, que se refere a um objeto temporário.

Então, mais uma vez, o mesmo objeto temporário pode ser facilmente "visto" como um rvalue ou como um lvalue, dependendo de que tipo de expressão (que tipo de Caminho de acesso) você costuma "olhar" para esse objeto.

Outras dicas

O Prasoon Saurav já vinculou um thread CLC ++ muito bom. Lá, James Kanze explica por que a pergunta não faz sentido. Tudo se resume a:

  • rvalue -ness é uma propriedade (booleana) de expressões - cada expressão é um lvalue ou um rvalue
  • Temporários são não expressões

Por esse motivo, a pergunta não faz sentido.

Um bom exemplo é o seguinte código:

int main() {
  const int& ri = 4;
  std::cout << ri << std::endl; 
}

O int temporário com valor 4 não é uma expressão. A expressão ri Isso é impresso não é temporário. É um LValue e refere -se a um temporário.

bem, esse operador de array retorna uma referência, qualquer função que retorne uma referência poderia ser considerada como fazendo a mesma coisa?todas as referências são const, embora possam ser lvalues, elas modificam o que fazem referência, não a referência em si.o mesmo é verdade para o *operador,

*(a temp pointer) = val;

Juro que costumava usar algum compilador que passava valores temporários para qualquer função que recebesse uma referência,

então você poderia ir:

int Afunc()
{
   return 5;
}

int anotherFunc(int & b)
{
    b = 34;
}


anotherFunc(Afunc());

não consigo encontrar um que permita fazer isso agora, a referência deve ser const para permitir a passagem de valores temporários.

int anotherFunc(const int & b);

de qualquer forma, as referências podem ser lvalues ​​​​e temporárias, o truque é que a referência em si não é modificada, apenas o que ela faz referência.

se você contar o-> operador como operador, então ponteiros temporários podem ser lvalores, mas a mesma condição se aplica: não é o ponteiro temporário que seria alterado, mas aquilo para o qual ele aponta.

Uma operação de indexação de matriz é temporária e um LValue, algo como um [10] = 1 é um exemplo do que você está procurando; O LValue é um ponteiro temporário e calculado.

Resposta curta:sim, mas não vou citar o padrão, porque provar esse ponto exigiria abordar todo tipo de problema temporário que existe.Por definição, um temporário tem uma vida inteira de uma declaração, portanto, atribuir coisas a uma seria, na melhor das hipóteses, um estilo ruim.

Resposta interessante:A elisão de cópia pode tornar (geralmente torna) um objeto temporário idêntico a um objeto lvalue.Por exemplo,

MyClass blah = MyClass( 3 ); // temporary likely to be optimized out

ou

return MyClass( 3 ); // likely to directly initialize object in caller's frame

Editar: quanto à questão de saber se existe algum objeto temporário nesses casos, §12.8/15 menciona

a operação de cópia pode ser omitida construindo o objeto temporário diretamente no destino da cópia omitida

o que indicaria que existe um objeto temporário que pode ser idêntico a um lvalue.

Depende do que você considera uma variável temporária.Você pode escrever algo como

#include <stdio.h>
int main()
{
    char carray[10];
    char *c=carray+1;
    *(c+2+4) = 9;
    printf("%d\n",carray[7]);
    return 0;
}

Isso é executado em VisualStudios e GCC.Você pode executar o código em teclado de código

Considero (c+2+4) um valor, embora queira atribuir a ele.Quando eu desreferenciasse, ele se tornaria um lvalue.Então, sim, todos os temporários são valores.Mas você pode transformar rvalues ​​(portanto, temporários) em um lvalue desreferenciando-o

Se não, alguém pode me fornecer um exemplo em que a produção temporária no código é um LValue?

O código a seguir vincula uma referência constante a um objeto temporário do tipo const float Criado pelo compilador:

int i;
const float &cfr = i;

O comportamento é "Até parece":

int i;
const float __tmp_cfr = i; // introduced by the compiler
const float &cfr = __tmp_cfr;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top