經過前兩次實驗,大部分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的標准,為開發提供更多方便。