cout < orden de llamada a las funciones que imprime?


El siguiente código:

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

Imprime " ba " en la consola

Mientras que:

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

Imprime "ab" ¿por qué es esto?

Parece como si cout está llamando a la función más externa (más cercana a la ;) primero y trabajando su camino, ¿es esa la forma en que se comporta?

 25
Author: Jim Lewis, 2010-01-25

3 answers

No hay un punto de secuencia con el operador << por lo que el compilador es libre de evaluar primero cualquiera de las funciones dequeue. 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 el orden en el que se evalúa) es <<'ed al resultado de <<'ing la primera (si entiendes lo que estoy diciendo).

Así que el compilador es libre de traducir su código a alguna cosa como cualquiera de estos (pseudo intermedio c++). Este 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 a lo que corresponden los temporales en la expresión original.

cout << myQueue.dequeue() << myQueue.dequeue();
|       |               |    |               |
|       |____ tmp1 _____|    |_____ tmp2 ____|
|                       |
|________ tmp3 _________|
 28
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-24 23:15:55

La llamada de tu ejemplo:

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

Se traduce como la siguiente expresión con dos llamadas de la función operator<<:

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

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

 7
Author: mloskot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-24 23:41:59

Desde C++17 el comportamiento de este código ha cambiado; el operando izquierdo de << está secuenciado antes que el operando derecho de <<, incluso cuando es un operador sobrecargado. La salida ahora debe ser ab.

Para más información ver: ¿Cuáles son las garantías de orden de evaluación introducidas por C++17?.

 0
Author: M.M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-27 04:31:51