cout << order of call to functions it prints?

问题描述 投票:0回答:3

以下代码:

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

将“ba”打印到控制台

同时:

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

打印“ab”这是为什么?

看起来好像 cout 首先调用最外层(最接近 ;)的函数并按其方式工作,这是它的行为方式吗?

c++ cout order-of-execution sequence-points
3个回答
32
投票

<<
运算符没有序列点,因此编译器可以首先评估任一
dequeue
函数。可以保证的是,第二个
dequeue
调用的结果(按照它在表达式中出现的顺序,而不一定是它的求值顺序)被
<<
' 转换为
<<
' 的结果第一个(如果你明白我的意思)。

所以编译器可以自由地将你的代码翻译成类似的东西(伪中间c++)。这并不是一份详尽的列表。

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

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

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

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

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

9
投票

您的示例中的调用:

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

通过两次调用

operator<<
函数转换为以下表达式:

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

cout
myQueue.dequeue()
的评估顺序未指定。然而,
operator<<
函数调用的顺序是明确指定的,如
1
2

标记

7
投票

自 C++17 起,此代码的行为发生了变化;

<<
的左操作数在
<<
的右操作数之前排序,即使它是重载运算符也是如此。现在的输出必须是
ab

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

© www.soinside.com 2019 - 2024. All rights reserved.