以下代码:
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 首先调用最外层(最接近 ;)的函数并按其方式工作,这是它的行为方式吗?
<<
运算符没有序列点,因此编译器可以首先评估任一 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 _________|
您的示例中的调用:
cout << myQueue.dequeue() << myQueue.dequeue();
通过两次调用
operator<<
函数转换为以下表达式:
operator<<( operator<<( cout, myQueue.dequeue() ), myQueue.dequeue() );
-------------------- 1
---------2
cout
、myQueue.dequeue()
的评估顺序未指定。然而,operator<<
函数调用的顺序是明确指定的,如1
和2
标记
自 C++17 起,此代码的行为发生了变化;
<<
的左操作数在 <<
的右操作数之前排序,即使它是重载运算符也是如此。现在的输出必须是 ab
。
如需进一步阅读,请参阅:C++17 引入的求值顺序保证是什么?.