2010-03-21 49 views
3

流插入運算符的關聯性是rtl,忘記這個事實有時會導致運行時錯誤或邏輯錯誤。 例如:這裏有什麼問題?關聯?評估訂單?如何更改訂單?

一號通

int F() 
{ 
    static int internal_counter c=0; 
    return ++c; 
} 
在主函數

//....here is main() 
cout<<」1st=」<<F()<<」,2nd=」<<F()<<」,3rd=」<<F(); 

,輸出是:

1st=3,2nd=2,3rd=1 

這是從我們期望在第一不同看。

2階 假設我們有這樣的堆棧數據結構的實現:

// 
    //... a Stack<DataType> class …… 
    // 

    Stack<int> st(10); 
    for(int i=1;i<11;i++) 
     st.push(i); 

cout<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl; 

預期的輸出是一樣的東西:

10 
9 
8 
7 

但我們有:

7 
8 
9 
10 

沒有內部錯誤< <實現,但它可以是如此混亂... 最後[:-)]我的問題:有什麼辦法通過重載它來改變運算符的關聯性嗎?

你認爲這可能是無法扭轉?我的意思是可以通過修改或更改開源STL來更改順序?

回答

5

是右結合的唯一的東西是賦值運算符。參見該標準的§5.4至5.18。 <<運算符從左到右進行評估,或者消息將以語法爲後向,而不是內容。內容是由於副作用,除了(如尼爾所提到的)「短路」& &和||以及逗號之外,這些副作用在C++中是無序的。

+0

@Sorush:這沒關係,你能接受尼爾的答案,如果你想... – Potatoswatter 2010-03-21 15:50:02

10

不,沒有。但我認爲你可能會混淆評價秩序。唯一指定評估順序的運營商是& &,||和(逗號)。當你說:

cout<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl; 

編譯器可以計算的子表達式,如它喜歡的任何命令,這是什麼原因造成的意外輸出st.pop()。

2

要看到這是如何評價的問題的順序,而不是一個關聯問題,修改代碼以這樣的:

int a = st.pop(); 
int b = st.pop(); 
int c = st.pop(); 
cout << a << endl << b << endl << c << endl;