vector<vector<int> >中>>之間的空格是否是必須的?
01-04
在某些書中看到 vector&
即寫成vector&&>的">&>"應該寫成"> &>"否則會被錯判成&>&>操作符 &>的形式但是在實際使用中我發現即使寫 vector& &> 編譯器也不會報錯,這是個別編譯器的特別優化還是標準中要求的
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
詞法解析依照最長子串原則,兩個大於號會被認為是右移符,為了解決題目中描述的讓程序員寫代碼難受的問題,編譯器和標準可以特殊照顧,不過由於模板參數也可以是個右移int表達式,因此m&
C標準的詞法解析的規定是最長子串原則,也就是編譯器從某個字元開始解析token,選擇最長的合法token,例如&>&>=雖然可以有幾種解釋:
1 大於、大於、賦值2 大於、大於等於3 右移、賦值4 右移增量賦值但根據最長子串原則,應該按4解析
實際上這也是絕大多數語言的詞法解析規定按照C語言的合法的符號,C標準這樣規定沒啥問題,可能出現的問題是有人寫出a=b/*c這種/*被解釋為注釋開始的情況,不過一般代碼規範也規定要加適當空格,所以不嚴重但是到了C++,很多編譯器還按照這樣實現,在模板的兩個反尖括弧上就會出現問題,因為連續兩個反尖括弧按上面規定,是解析為右移符號,這時候就像題主說的,要在中間加個空格(連續空白都行,比如空格回車tab)才能編譯通過,但是加空格又違反直覺,看著不舒服從技術上說,在解析模板參數過程中碰到&>&>,將其特殊處理為兩個反尖括弧並不是什麼難事,所以C++11就在原先規定的基礎上新增規定,明確允許了這種做法,事實上在此之前,有的編譯器已經實現了,為了程序員編碼方便,就好像C99並不允許for(int i.....)這種,定義必須寫外面,但仍然有編譯器額外支持一樣最後一句的意思是,這個支持並不是一個很嚴謹的規定,而是從實際出發的一個權衡,例子就是上面說的,由於模板參數允許是int類型,所以一個右移表達式也可傳入,這時候編譯器解析模板參數,發現了&>&>,那究竟是一個右移符,還是可能是連續反尖括弧,是沒法預測程序員的想法的(如果分析全文倒是可以,但這樣引入沒必要的複雜性),其實就算在C++11出這個規定之前,如果是想把一個大於運算的結果作為參數,也會有這個問題,碰到&>符號是反括弧還是大於運算,不明確
而C++規定碰到&>或&>&>認為是反括弧的原因是從實際出發的:1 用int(或bool)做參數並傳入右移(或大於)表達式是一個相對嵌套尖括弧很少的情況2 通過加入圓括弧可以無歧義很清晰分割,m&C++98要,C++03之後不用。
插句題外話:數組裡面套數組,總覺得這樣挺怪。。。前面也加個空格,就順眼多了,類似的 vector&< pair&
C++11以後不是必須的,C++11以前用VC++也不是必須的,舊標準反人類,連VC6都能搞定的事情,這幫ISO竟然不敢搞。
就看C++的新標準什麼時候在任何情況(只沒有覆蓋到名字的時候)下讓this-&>都能省略。這是我摔過的一個大坑,以前寫跨平台引擎,vs下完全沒問題,自然都這麼寫。等代碼積累接近50萬行,開始做環境集成,然後gcc和xcode下編不過我就傻了…
你寫成vector&< vector&
我記得上編譯原理的課的時候就有講到這是gcc的bug……難道這個bug還進過標準?
C11明確要求要去除此二義性的...(如果我沒記錯的話)以前的版本這個算BUG...(如果我沒記錯的話VS2003有這個BUG...到VS2008被修復了)
c++11以前是必須的
以前有大神告訴我說,是必須的,因為如果不是空格,&>&>會被編譯器認為是重載。
好久沒用c艹了,不知道現在怎麼樣了……試過在gcc編譯時報錯,vs2012正常。
在某個版本之前(C++11或者14)是不可以連在一起的.
這個版本之後就可以了「&> &>":vc6.0必須有空格,否則編譯出錯,vs2005以後有無皆可。
c++ primer 第五版 中文版p87 英文版p97
因為以前寫解析的匹配演算法會認為 &>&> 是右移符號。後面這個匹配被修正了。
推薦閱讀:
※Visual Studio 為何沒有 64 位的版本?
※Visual C++ 6以debug模式編譯很拙笨,為何要做無用功?
※如何拒絕編譯器將函數內聯處理?
※為什麼編譯器不能「合成「純虛析構函數的函數定義??
※第一個 C 語言編譯器是用什麼語言編寫的?