[問題] cout.operator<<() 和函式的執行順序

看板C_and_CPP作者 (Mellivora Capensis)時間12年前 (2013/05/07 01:31), 編輯推噓1(1013)
留言14則, 6人參與, 最新討論串1/1
以下程式碼很簡單,我想大家都知道輸出是什麼 #include <iostream> using namespace std; int fun(int n) { // cout << "n:" << n <<endl; return n; } int main(void) { cout << "start:" << fun(10); getchar(); return 0; } 但是當你把fun()的註解取消時,問題就浮現了 cout敘述是先執行fun(10),所以fun內的敘述會先被執行,所以start出現於最後面 請問這該如何解釋呢? 於是我想了幾個理由: (1).fun()有小括弧,優先權最高,所以先執行 (2).<<右結合,所以出現在最右邊的fun(10)先執行 (2)感覺好像是對的,因為如果改成這樣,最右邊的fun(10)會先執行 cout << fun(20) <<"start:" << fun(10); 問題是<<是運算子重載,在位移運算子的時候是右結合,可是重載之後就不是了 因為回丟的物件是ostream實際上使用應該是如下,應該是左結合才是 cout.operator<<(fun(20)).operator<<("start").operator<<(fun(10)) 有人知道為什麼嗎? 謝謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 175.180.87.24

05/07 01:34, , 1F
在所有 function calls(operator<<) 之前, 你的引數必
05/07 01:34, 1F

05/07 01:35, , 2F
需先準備好(evaluation), 這跟結合方向沒有關係.
05/07 01:35, 2F

05/07 01:38, , 3F
你想要依序執行的話可以寫成像 <iomanip> 裡的 setw()
05/07 01:38, 3F

05/07 01:39, , 4F
一樣回傳一個 functor http://goo.gl/MzlCP 該仿函式
05/07 01:39, 4F

05/07 01:40, , 5F
重載了 operator() 利於在 cout << 作 cascading 時用
05/07 01:40, 5F

05/07 01:41, , 6F
特殊呼叫方法把 cout 丟給你的 functor, 那時才做事
05/07 01:41, 6F

05/07 01:46, , 7F
打錯應該是像 std::left, http://goo.gl/N6fq5
05/07 01:46, 7F
您好,請問函數的執行順序純粹跟編譯器的實作有關嗎? 與結合順序無關嗎? 如:cout<<f(1)<<f(2)<<f(3); 實際執行時是:f(3)->f(2)->f(1) 我記得C語言的printf的參數執行順序是跟編譯器實作有關,標準的ANSI-C並未規定 如:printf("%d,%d",f(1),f(2)); 有可能是f(1)->f(2),也有可能是f(2)->f(1) ※ 編輯: RATEL 來自: 175.180.87.24 (05/07 07:38)

05/07 08:20, , 8F
<< 是左結合。 所以 32 << 2 << 1 答案是 256 而非 512
05/07 08:20, 8F

05/07 15:43, , 9F
結合律與執行時運算順序無關. Call object method 相當於多傳
05/07 15:43, 9F

05/07 15:44, , 10F
一個 this 進去, 所以物件跟參數的執行是 unspecified
05/07 15:44, 10F

05/07 15:44, , 11F
g++ 決定 fun(10) 算完再算 cout.operator<<("start:")
05/07 15:44, 11F

05/07 16:22, , 12F
這怎麼好像是undefined behavior? 據說gcc跟VC會不一樣
05/07 16:22, 12F

05/07 17:29, , 13F
的確是不一定
05/07 17:29, 13F

05/07 18:27, , 14F
這不是undefined而是unspecified
05/07 18:27, 14F
文章代碼(AID): #1HX-a1Od (C_and_CPP)