2010-01-24 62 views
23

下面的代码:cout <<打印功能的调用顺序?

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

打印 “八” 到控制台

同时:

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

打印 “AB” 这是为什么?

看起来好像cout最先调用最靠外的(最接近;)函数并且正在工作,它的行为方式是什么?

+0

所有答案都在哪里去了?现在只有一个? – finiteloop 2010-01-24 22:53:27

+1

回答者删除了他们,因为他们意识到他们错了。 – 2010-01-24 22:54:55

+1

有些人在发现错误时会删除答案。 – 2010-01-24 22:55:40

回答

28

运算符<<没有序列点,因此编译器可以自由地首先评估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 _________| 
+0

因此,在顶部的例子中, std :: ostream&tmp3 = cout << tmp1; tmp3 << tmp2; 就像在说“cout << tmp1 << tmp2;”?或者我错过了什么? – finiteloop 2010-01-24 22:57:37

+0

@segfault:是的,因为这是'''在C++语法中关联的方式。 'a << b << c'总是分组为'(a << b)<< c'。 – 2010-01-24 23:03:16

+0

但是通过这种逻辑,不会说cout << a << b是说(cout << a)<< b并且做任何必要的事情来关闭第一个(即调用myQueue.dequeue())? – finiteloop 2010-01-24 23:07:39

6

从你的榜样召唤:

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

转换为下面的表达operator<<功能的两个电话:

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

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

相关问题