用C++11替代Boost的實驗之三


轉載請注明出處為KlayGE游戲引擎,本文的永久鏈接為http://www.klayge.org/?p=2330

經過前兩次實驗,大部分C++11里有的boost組件都被替換成了C++11中相應的。剩下的還有random庫和bind/function/mem_fn/ref/smart_ptr這一組。看來,到了不得不改代碼的時候了。

random

第一次實驗里提到過,random雖然在boost和C++11都有,但接口不相同,所以原先我用Boost.Random實現的代碼,無法直接替換成C++11的。翻了一遍boost文檔,發現現在的boost其實有實現了一套名字和C++11相同的組件,於是我重寫了所有用到random的地方,用和C++11兼容的代碼,就解決了這個問題。好在random用得不多,改幾個地方就都好了。

bind/function/mem_fn/ref/smart_ptr

這幾個組件相互依賴,要么全換,要么不換。再加上牽扯面非常廣,修改起來幾乎都要rebuild所有代碼,進展非常緩慢。經過多次痛苦的rebuild之后,問題集中在了幾個地方:

signals2::disconnect

C++11的function的operator==只能和nullptr作比較,所以disconnect的時候一定會編譯失敗。按照boost文檔,signals2的正確用法應該是,connect的時候返回一個連接對象,在那上面調用disconnect。這樣避免了function的比較,同時也更高效。修改后這個地方正常了。

algorithm::string::split

可能是VC11的bind實現bug,bind(equal_to<char>(), ‘ ‘, _1)無法編譯。同樣參看文檔,用了更常見的is_any_of(” “),問題解決。

function值傳遞

這也很可能是VC11的bind實現bug。一個function如果用值傳遞傳給bind的functor,編譯沒問題,但執行的時候crash,debugger里看到的是那個function對象沒有被傳給真實的函數,而就被析構掉了,某一次傳遞被搞成了引用傳遞。於是這里只能放棄bind,用自己實現的functor代替。

沒有Variadic templates

因為VC11目前不支持Variadic templates,不能做可變參數的template。所以vc11的stl里,對於不同參數的bind,在實現上只能手寫展開。而他們估計偷懶了,只展開到了4個參數。如果bind要有更多參數,就只能改代碼,把一些參數合並入一個struct。

mem_fn和stdcall

由於VC11的mem_fn實現不完全,stdcall的成員函數無法通過mem_fn來使用。這里只能暫時用boost的mem_fn來湊或。

完成

至此,所有C++11里有的boost組件都得到了替換(除了mem_fn是不完全替換),同時仍然可以通過宏切換回boost的實現。在VC11和MinGW 4.7上通過了測試。隨着未來編譯器的發展,相信現在的一些限制會逐漸消失。也希望有更多組件成為TR2和C++1y的標准,為開發提供更多方便。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM