2010-01-24 6 views
23

el siguiente código:cout << orden de llamada a las funciones que imprime?

myQueue.enqueue('a'); 
myQueue.enqueue('b'); 
cout << myQueue.dequeue() << myQueue.dequeue(); 

impresiones "ba" a la consola

rato:

myQueue.enqueue('a'); 
myQueue.enqueue('b'); 
cout << myQueue.dequeue(); 
cout << myQueue.dequeue(); 

impresiones "ab" ¿por qué es esto?

Parece que cout llama primero a la función más externa (más cercana a la;) y se abre paso, ¿así es como se comporta?

+0

¿A dónde fueron todas las respuestas? ahora solo hay uno? – finiteloop

+1

Los respondedores los borraron porque se dieron cuenta de que estaban equivocados. –

+1

Algunas personas eliminan las respuestas cuando descubren que están equivocadas. –

Respuesta

28

No hay punto de secuencia con el operador << por lo que el compilador puede evaluar primero la función dequeue primero. Lo que está garantizado es que el resultado de la segunda llamada dequeue (en el orden en el que aparece en la expresión y no necesariamente en el orden en que se evalúa) es << 'ed al resultado de <<' el primero (si consigue lo que estoy diciendo).

Así que el compilador puede traducir su código a algo como cualquiera de estos (pseudo intermedio C++). Esto no pretende ser una lista exhaustiva.

auto tmp2 = myQueue.dequeue(); 
auto tmp1 = myQueue.dequeue(); 
std::ostream& tmp3 = cout << tmp1; 
tmp3 << tmp2; 

o

auto tmp1 = myQueue.dequeue(); 
auto tmp2 = myQueue.dequeue(); 
std::ostream& tmp3 = cout << tmp1; 
tmp3 << tmp2; 

o

auto tmp1 = myQueue.dequeue(); 
std::ostream& tmp3 = cout << tmp1; 
auto tmp2 = myQueue.dequeue(); 
tmp3 << tmp2; 

Esto es lo que los provisionales corresponden a la expresión original.

cout << myQueue.dequeue() << myQueue.dequeue(); 
|  |    | |    | 
|  |____ tmp1 _____| |_____ tmp2 ____| 
|      | 
|________ tmp3 _________| 
+0

entonces, en el ejemplo superior, sería std :: ostream & tmp3 = cout << tmp1; tmp3 << tmp2; ser como decir "cout << tmp1 << tmp2;"? O algo que me estoy perdiendo? – finiteloop

+0

@segfault: Sí, porque esa es la forma en que '<<' se asocia en la gramática C++. 'a << b << c' siempre agrupa como' (a << b) << c'. –

+0

pero según esa lógica, wouldnt diciendo cout << a << b estar diciendo (cout << a) << b y hacer lo necesario para abrir una primera (es decir, llamar a myQueue.dequeue())? – finiteloop

6

La llamada de su ejemplo:

cout << myQueue.dequeue() << myQueue.dequeue(); 

se traduce en la siguiente expresión con dos llamadas de operator<< función:

operator<<(operator<<(cout, myQueue.dequeue()), myQueue.dequeue()); 
-------------------- 1 
---------2 

El orden de evaluación de cout, myQueue.dequeue() está especificado. Sin embargo, el orden de las llamadas a la función operator<< está bien especificado, como se marcó con 1 y 2

Cuestiones relacionadas