Le doute sur une question d'entrevue C de
Question
J'ai lu parmi lesquels il y a un que des puzzles me:
Q: Quand les variables temporaires créées par le compilateur C
A:. A condition que le paramètre de fonction est une "référence const", compilateur génère la variable temporaire à la suite de 2 façons
a) L'argument réel est le type correct, mais il est Lvalue
double Cube(const double & num) { num = num * num * num; return num; } double temp = 2.0; double value = cube(3.0 + temp); // argument is a expression and not a Lvalue
b) L'argument réel est du mauvais type, mais d'un type qui peut être converti en le type correct
long temp = 3L; double value = cuberoot(temp); // long to double conversion
Ma question est une fois que l'argument de la fonction est un référence const , pourquoi le compilateur génère la variable temporaire, n'est pas contradictoire? De plus, si la fonction Cube ne pas compiler, car il modifie l'argument const?
La solution
Vous êtes autorisé à passer les résultats d'une expression (y compris celle de la coulée implicite) à une référence à const. La raison est que si (const X & value)
peut être moins cher à utiliser, en fonction de la copie coût du type type X, que (X value)
, l'effet est à peu près la même; value
se habitue, mais pas modifiée (sauf certains const-coulée de casse-gueule). Par conséquent, il est inoffensif pour permettre à un objet temporaire à créer et transmis à la fonction.
Vous n'êtes pas autorisé à le faire avec pointeur à const ou référence à la non-const, parce inattendus (et mauvaises) choses peuvent se produire, comme on pouvait s'y attendre la longue température à couler de nouveau à long, ce qui ne va pas se produire.
Vous avez raison à propos num = num * num * num;
être invalide. C'est un bogue dans le texte, mais l'argument qu'elle détient.
Autres conseils
Je ne vois rien de contradictoire ici. Si l'argument n'est pas une lvalue, ou est de mauvais type, la référence ne peut pas être fixé directement à l'argument pour des raisons évidentes; d'où la nécessité d'un intermédiaire temporaire du type correct. La référence est attaché à ce lieu temporaire.
La fonction Cube
est en effet cassé (mal formé) car il tente de modifier une valeur de const
.
On dirait tort de me - et gcc génère une erreur:
const_ref.cpp: In function ‘double cube(const double&)’:
const_ref.cpp:3: error: assignment of read-only reference ‘num’
Le compilateur peut générer une variable temporaire. Il ne doit pas.
Et oui, Cube
ne devrait pas compiler réellement.
Parce que dans les deux cas, il n'y a pas d'objet non temporaire du type correct.
Je crois que vous avez raison sur le cube de fonction ne pas compiler. Quoi qu'il en soit, cela devrait échouer, et il le fait sur mon compilateur (VC ++ 2008).
En ce qui concerne la création d'un temporaire:
Une valeur temporaire pour sauvegarder la référence const sera créé à chaque fois que l'argument réel:
i) ne sont pas du type correct pour la référence et, ii) peut être converti implicitement le type correct.
Dans l'exemple a) de votre question, une double
temporaire est créée pour maintenir la valeur 3.0 + temp
. Ensuite Cube()
est appelée avec une référence const
au temporaire. Ceci est parce que vous ne pouvez pas avoir une référence à 3.0 + temp
parce que ce n'est pas une variable (il est un rvalue - le résultat d'une expression) et il n'a pas d'adresse de mémoire, et ne peut pas revenir la référence. Implicitement, le compilateur va créer un double
temporaire, puis attribuez-lui la valeur de 3.0 + temp
.
Dans votre exemple b), vous avez une long
, mais votre fonction nécessite un double
. Le compilateur convertit implicitement un long
à un double
. Il fait cela en créant un double
temporaire, lui attribuant la valeur convertie de temp
, puis en créant une référence de const
à l'arrêt temporaire, et en passant que la référence à cuberoot
Oui. Cube (), comme vous l'avez montré ici, ne parviennent pas à compiler.