cout <<打印函数的调用顺序?

fin*_*oop 27 c++ cout

以下代码:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue() << myQueue.dequeue();
Run Code Online (Sandbox Code Playgroud)

将"ba"打印到控制台

而:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue();
cout << myQueue.dequeue();
Run Code Online (Sandbox Code Playgroud)

打印"ab"为什么会这样?

似乎cout首先调用最外层(最接近;)函数并且正在进行中,它的行为方式是什么?

CB *_*ley 30

<<运算符没有序列点,因此编译器可以自由地dequeue首先评估任一函数.保证的是第二次dequeue调用的结果(按照它在表达式中出现的顺序而不一定是它被评估的顺序)是<<' 第一次调用的结果<<'(如果你得到了我的话)我在说.

因此编译器可以自由地将您的代码转换为某些内容(伪中间c ++).这不是一个详尽的清单.

auto tmp2 = myQueue.dequeue();
auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;
Run Code Online (Sandbox Code Playgroud)

要么

auto tmp1 = myQueue.dequeue();
auto tmp2 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;
Run Code Online (Sandbox Code Playgroud)

要么

auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
auto tmp2 = myQueue.dequeue();
tmp3 << tmp2;
Run Code Online (Sandbox Code Playgroud)

这是临时表在原始表达式中对应的内容.

cout << myQueue.dequeue() << myQueue.dequeue();
|       |               |    |               |
|       |____ tmp1 _____|    |_____ tmp2 ____|
|                       |
|________ tmp3 _________|
Run Code Online (Sandbox Code Playgroud)

  • 关联性没有说明子表达式的评估顺序.`cout << a << b`总是意味着`(cout << a)<< b`但是编译器可以先自由地评估`b`,然后是'a`,然后是第一个````操作和第二.这正是我在答案中提出的观点. (6认同)

mlo*_*kot 8

来自你的例子的电话:

cout << myQueue.dequeue() << myQueue.dequeue();
Run Code Online (Sandbox Code Playgroud)

通过两次operator<<函数调用转换为以下表达式:

operator<<( operator<<( cout, myQueue.dequeue() ), myQueue.dequeue() );
-------------------- 1
---------2
Run Code Online (Sandbox Code Playgroud)

评价的顺序cout,myQueue.dequeue()是不确定的.但是,operator<<函数调用的顺序已明确指定,标记为12


M.M*_*M.M 8

自 C++17 起,此代码的行为发生了变化;即使它是重载运算符, 的左操作数也会<<排在 的右操作数之前<<。现在的输出必须是ab.

如需进一步阅读,请参阅:C++17 引入的求值顺序保证是什么?