原來我總結過c++的一些類型轉換函式:http://blog.csdn.net/callmeback/article/details/4040583
static_cast, dynamic_cast, const_cast, reinterpret_cast其中各有各的用處和弊端。
boost的Conversion庫分別實現了四個類型轉換函式:polymorphic_case, polymorphic_downcast, numeric_cast和lexical_cast。
設計的主要原則是:代碼必須準確運行而且清晰的表達作者的意圖。
polynorphic_cast提供更好的型別安全。在c++類型轉換中與dynamic_cast是類似的,只要看一眼polynorphic_cast的實現代碼就可以明白:polynorphic_cast調用了dynamic_cast,並且當傳回值為0時就是出錯的時候,所以polynorphic_cast直接拋出異常,節省了使用者的傳回值判斷操作,實現的是邏輯的改進。
適用情況:當返回0不是錯誤的情況下,請用dynamic_cast;引用轉換請用dynamic_cast;剩下的推薦用polynorphic_cast。
template <class Target, class Source>inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET){ Target tmp = dynamic_cast<Target>(x); if ( tmp == 0 ) throw std::bad_cast(); return tmp;}
polynorphic_downcast提供更好的型別安全防護。從實現代碼來看polynorphic_downcast完全就是static_cast。由於static_cast比dynamic_cast效率更高,所以有用武之地,但是從來不保證轉換是合法的。polynorphic_downcast在debug模式下採用dynamic_cast測試了一下正確性,以求在release模式下預設為正確的。但是不敢保證是正確的。所以我覺得,能不用就別用了。
template <class Target, class Source>inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET){ BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error return static_cast<Target>(x);}
numeric_cast顧名思義是數字轉換,提供安全的範圍檢查。資料類型有8位,16位,32位,64位等等,還分為無符號和有符號兩種還有char。當從小記憶體向大記憶體轉換時往往很容易,返回來的時候往往會有出問題的隱患。而且有符號數和無符號數之間的轉換有時候並不是作者的真實意圖。
使用numeric_cast當資料截斷時輸出異常。而short s = 65537則不會。
#include <iostream>#include <boost/cast.hpp>int _tmain(int argc, _TCHAR* argv[]){int num = 65537;try{short s = boost::numeric_cast<short>(num);}catch(boost::bad_numeric_cast& e){std::cout << e.what() << std::endl;}getchar();return 0;}
無符號數有迴繞功能,看以下代碼就可以看出。
#include <iostream>#include <boost/cast.hpp>int _tmain(int argc, _TCHAR* argv[]){unsigned char max = 0xff;unsigned char maxmore = max + 1;unsigned char diff = maxmore - max;printf("max = %d, maxmore = %d, maxmore - max = %d\n",max, maxmore, diff);getchar();return 0;}
無符號數和有符號數在相同資料位元的情況下做類型轉換,numeric_cast會進行範圍判斷,不再舉例。
double向float轉換不會報錯,例如:
double d = 0.123456789123456;float f = 0.123456;try{f = boost::numeric_cast<float>(d);}catch(boost::bad_numeric_cast& e){std::cout << e.what();}
浮點數向整數轉換時截斷小數部分。
所以,使用numeric_cast的情況是:資料類型大小不一樣情況下進行複製和比較;無符號和有符號之間進行賦值和比較;從函數傳回型別向數值變數賦值時。總之,一切有可能導致資料類型範圍變化的情況都應該使用。
lexical_cast提供文字轉換的服務。
我們有很多情況下需要把字串轉換成數值,把數值轉換成字串。sprintf和atof、atol等等函數派上了用場而且不厭其煩的要判斷最終的返回結果是否是正確的。現在lexical_cast用一個函數解決了這些問題,並且在轉換錯誤時返回異常boost::bad_lexical_cast。
一個泛型代碼就替代了眾多的情況,不得不感歎boost,我愛死你了。
#include <boost/lexical_cast.hpp>template <typename T> std::string to_string(const T& t){try{return boost::lexical_cast<std::string>(t);}catch (boost::bad_lexical_cast& e){return "";}}
從字串到數值的正向反向轉換及其方便。還可以實現各種自訂類型的轉換,不過需要你自己實現了。