27 votes

Toutes les valeurs temporaires sont-elles en C ++?

J'ai codé en C ++ ces dernières années. Mais il y a une question que je n'ai pas pu comprendre. Je veux demander, sont tous temporaires en C ++, rvalues?

Si non, quelqu'un peut-il me donner un exemple où temporaire produit dans le code est une valeur l ?

34voto

AndreyT Points 139512

Pas de.

Le langage C++ spécification jamais fait la simple affirmation que l'on vous demande. Il ne dit pas n'importe où dans la langue standard que "tous les objets temporaires sont rvalues". En outre, la question elle-même est un peu mal choisi, puisque la propriété d'être une rvalue dans le langage C++ n'est pas une propriété d'un objet, mais plutôt une propriété d'une expression (c'est à dire une propriété de son résultat). C'est en fait la façon dont il est défini dans la spécification du langage: pour les différents types d'expressions, on dit que quand le résultat est une lvalue et quand c'est une rvalue. Entre autres choses, cela signifie en fait qu'un objet temporaire peut être consulté en tant que rvalue ainsi qu'une lvalue, en fonction de la forme de l'expression qui est utilisée pour effectuer l'accès.

Par exemple, le résultat de littéral 2 + 3 expression est évidemment une rvalue, temporaire de type int. Nous ne pouvons pas appliquer le unaire & depuis unaire & nécessite une lvalue que son opérande

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

Cependant, comme nous le savons tous, une référence constante peut être attaché à un objet temporaire, comme dans

const int &ri = 2 + 3;

Dans ce cas, la référence est attaché temporaire, l'extension de la durée de vie de ce dernier. Évidemment, une fois que c'est fait, nous avons accès à cette même temporaire comme une lvalue ri, puisque les références sont toujours lvalues. Par exemple, nous pouvons facilement et légalement s'appliquer unaire & de la référence et obtenir un pointeur temporaire

const int *pi = &ri;

avec le pointeur reste parfaitement valable aussi longtemps que le temporaire persiste.

Un autre exemple évident de la lvalue l'accès à un objet temporaire est lorsque nous avons accès à un objet temporaire de type de classe par le biais de son this pointeur. Le résultat de l' *this est une lvalue (comme c'est toujours le cas avec le résultat de l'unaire * appliqué à un pointeur de données), mais il ne change pas le fait que l'objet réel pourrait facilement être une mesure temporaire. Pour une classe donnée de type T, de l'expression, T() est une rvalue, comme il est dit explicitement dans la langue standard, mais l'objet temporaire accessible par *T().get_this() d'expression (avec l'évidente mise en œuvre de l' T::get_this()) est une lvalue. Contrairement à l'exemple précédent, cette méthode vous permet d'obtenir immédiatement un non-const-qualifiés lvalue, qui se réfère à un objet temporaire.

Donc, encore une fois, le même objet temporaire peut facilement être "vu" comme une rvalue ou comme une lvalue, selon le type de l'expression (quel type de chemin d'accès) que vous utilisez pour "regarder" à l'objet.

6voto

MSalters Points 74024

Prasoon Saurav déjà lié d'une très bonne ctc++ fil. Là, James Kanze explique pourquoi la question n'a pas vraiment de sens. Il se résume à:

  • rvalue-ness est un (boolean) les biens d'expressions - chaque expression est une lvalue ou une rvalue
  • temporaires sont pas des expressions

Pour cette raison, la question n'a pas de sens.

Un bon exemple est le code suivant:

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

La temporaire de type int, avec la valeur 4 n'est pas une expression. L'expression ri imprimé n'est pas temporaire. C'est une lvalue, et se réfère à une mesure temporaire.

1voto

matt Points 1675

bien que la matrice de l'opérateur renvoie une référence, une fonction qui renvoie une référence pourrait être envisagé de faire la même chose? toutes les références sont const, alors qu'ils peuvent être lvalues, ils modifier ce qu'ils référence, et non la référence elle-même. en est de même pour l' *de l'opérateur,

*(a temp pointer) = val;

Je vous jure que je l'habitude d'utiliser certains compilateur qui passera temp valeurs d'une fonction qui a eu une référence,

donc, vous pouvez aller de l':

int Afunc()
{
   return 5;
}

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


anotherFunc(Afunc());

pouvez pas en trouver un qui vous permet de le faire maintenant, la référence doit être const afin de permettre la transmission de temp valeurs.

int anotherFunc(const int & b);

de toute façon, les références peuvent être lvalues et temporaire, l'astuce étant la référence, c'est l'auto n'est pas modifié, seulement ce qu'il référence.

si vous comptez l'-> de l'opérateur que l'opérateur, temporaire de pointeurs peuvent être lvalues, mais la même condition s'applique, ce n'est pas le temp de pointeur qui serait modifié, mais la chose qu'il indique.

0voto

Andrew McGregor Points 7641

Une opération d'indexation de tableau est à la fois une valeur temporaire et une valeur l, quelque chose comme [10] = 1 est un exemple de ce que vous recherchez; la lvalue est un pointeur calculé temporaire.

0voto

acidzombie24 Points 28569

Cela dépend de ce que vous considérez comme une variable temporaire. Vous pouvez écrire quelque chose comme

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

Cela fonctionne dans VisualStudios et GCC. Vous pouvez exécuter le code dans le codepad

Je considère (c +2 +4) une valeur bien que je veuille lui attribuer. Quand je le déréférencerais, cela deviendrait une valeur l. Alors oui, tous les temporaires sont des valeurs. Mais vous pouvez faire de rvalues (donc une valeur temporaire) une lvalue en la déréférençant

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X