boost.conversion 庫由兩個檔案組成。分別在boost/cast.hpp
檔案中定義了boost::polymorphic_cast
和boost::polymorphic_downcast
這兩個型別轉換操作符, 在boost/lexical_cast.hpp
檔案中定義了boost::lexical_cast
。
boost::polymorphic_cast
和boost::polymorphic_downcast
是為了使原來用dynamic_cast
實現的型別轉換更加具體。具體細節,如下例所示。
struct father; };
struct mother
; };
struct child :
public father,
public mother
; void func(father *f)
int main()
本例使用dynamic_cast
型別轉換操作符兩次: 在func()
函式中,它將指向父類的指標轉換為指向子類的指標。在main()
中, 它將乙個指向父類的指標轉為指向另乙個父類的指標。第乙個轉換稱為向下轉換(downcast),第二個轉換稱為交叉轉換(cross cast)。
通過使用 boost.conversion 的型別轉換操作符,可以將向下轉換和交叉轉換區分開來。
#include struct father; };
struct mother
; };
struct child :
public father,
public mother
; void func(father *f)
int main()
boost::polymorphic_downcast
型別轉換操作符只能用於向下轉換。 它內部使用static_cast
實現型別轉換。 由於static_cast
並不動態檢查型別轉換是否合法,所以boost::polymorphic_downcast
應該只在型別轉換是安全的情況下使用。 在除錯(debug builds)模式下,boost::polymorphic_downcast
實際上在assert ()
函式中使用dynamic_cast
驗證型別轉換是否合法。 請注意這種合法性檢測只在定義了ndebug
巨集的情況下執行,這通常是在除錯模式下。
向下轉換最好使用boost::polymorphic_downcast
, 那麼boost::polymorphic_cast
就是交叉轉換所需要的了。 由於dynamic_cast
是唯一能實現交叉轉換的型別轉換操作符,boost::polymorphic_cast
內部使用了它。 由於boost::polymorphic_cast
能夠在錯誤的時候丟擲std::bad_cast
型別的異常,所以優先使用這個型別轉換操作符還是很有必要的。相反,dynamic_cast
在型別轉換失敗使將返回0。 避免手工驗證返回值,boost::polymorphic_cast
提供了自動化的替代方式。
boost::polymorphic_downcast
和boost::polymorphic_cast
只在指標必須轉換的時候使用;否則,必須使用dynamic_cast
執行轉換。 由於boost::polymorphic_downcast
是基於static_cast
,所以它不能夠,比如說,將父類物件轉換為子類物件。 如果轉換的型別不是指標,則使用boost::polymorphic_cast
執行型別轉換也沒有什麼意義,而在這種情況下使用dynamic_cast
還會丟擲乙個std::bad_cast
異常。
雖然所有的型別轉換都可用dynamic_cast
實現,可boost::polymorphic_downcast
和boost::polymorphic_cast
也不是真正隨意使用的。 boost.conversion 還提供了另外一種在實踐中很有用的型別轉換操作符。 體會一下下面的例子。
#include #include #include int main()
型別轉換操作符boost::lexical_cast
可將數字轉換為其他型別。 例子首先將整數169轉換為字串,然後將字串轉換為浮點數。
boost::lexical_cast
內部使用流(streams)執行轉換操作。 因此,只有那些過載了operator<<()
和operator>>()
這兩個操作符的型別可以轉換。 使用boost::lexical_cast
的優點是型別轉換出現在一行**之內,無需手工操作流(streams)。 由於流的用法對於型別轉換不能立刻理解**含義, 而boost::lexical_cast
型別轉換操作符還可以使**更有意義,更加容易理解。
請注意boost::lexical_cast
並不總是訪問流(streams);它自己也優化了一些資料型別的轉換。
如果轉換失敗,則丟擲boost::bad_lexical_cast
型別的異常,它繼承自std::bad_cast
。
#include #include #include int main()catch (boost::bad_lexical_cast &e)
}
本例由於字串 "abc" 不能轉換為int
型別的數字而丟擲異常。
boost.numericconversion 可將一種數值型別轉換為不同的數值型別。 在c++裡, 這種轉換可以隱式地發生,如下面例所示。
#include int main()
由於從int
到short
的型別轉換自動產生,所以本例編譯沒有錯誤。 雖然本例可以執行,但結果由於依賴具體的編譯器實現而結果無法預期。 數字0x10000
對於變數 i 來說太大而不能儲存在short
型別的變數中。 依據c++標準,這個操作的結果是實現定義的("implementation defined")。 用visual c++ 2008編譯,應用程式顯示的是0
。 s 的值當然不同於 i 的值。
為避免這種數值轉換錯誤,可以使用boost::numeric_cast
型別轉換操作符。
#include #include int main()catch (boost::numeric::bad_numeric_cast &e)
}
boost::numeric_cast
的用法與c++型別轉換操作符非常相似。 當然需要包含正確的標頭檔案;就是boost/numeric/conversion/cast.hpp
。
boost::numeric_cast
執行與c++相同的隱式轉換操作。 但是,boost::numeric_cast
驗證了在不改變量值的情況下轉換是否能夠發生。 前面給的應用例子,轉換不能發生,因而由於0x10000
太大而不能儲存在short
型別的變數上,而丟擲boost::numeric::bad_numeric_cast
異常。
嚴格來講,丟擲的是boost::numeric::positive_overflow
型別的異常,這個型別特指所謂的溢位(overflow) - 在此例中是正數。 相應地,還存在著boost::numeric::negative_overflow
型別的異常,它特指負數的溢位。
#include #include int main()catch (boost::numeric::negative_overflow &e)
}
boost.numericconversion 還定義了其他的異常型別,都繼承自boost::numeric::bad_numeric_cast
。 因為boost::numeric::bad_numeric_cast
繼承自std::bad_cast
,所以catch
處理也可以捕獲這個型別的異常。
scala學習筆記(十六) 型別引數與隱式轉換
scala 中的型別引數晦澀難懂,不過有幾個基本要點可以記錄 t upperbound 上界,通俗理解t是 upperbound 的子類 t lowerbound 下界,通俗理解為t為 lowerbound 的超類 t comparable t 檢視界定,簡單理解為,t可以通過隱式轉換為後者 t o...
boost中型別轉換學習
型別轉換在很多時候需要使用上,方便且安全的轉換是很有必要的。從c語言的一些api到c 中提供的stringstream流都有很多方式可以實現,了解他們的特點可以讓我們在日常編碼中編寫出漂亮的 一 c語言中常用的型別轉換 char szbuf 100 int nvalue 100000000 spri...
型別轉換 數值操作
一 型別轉換函式 函式 描述 int x base 將x轉 換為乙個整數 其中base表示基數 long x base 將 x轉換為乙個長整數 float x 將 x轉換到乙個浮點數 complex real imag 建立乙個複數 str x 將 物件 x 轉換為字串 repr x 將物件 x 轉...