Boost 學(xué)習(xí)
作者:陳珍敬 Boost 安裝下載 boost 源代碼包,解壓,進(jìn)入 boost 目錄,執(zhí)行 ./configure-> 生成 Makefile-> 執(zhí)行 make 即可。 自動(dòng)執(zhí)行: ./tools/build/jam_src/bin.linuxx86/bjam -sPYTHON_ROOT=/usr -sPYTHON_VERSION=2.3 -sTOOLS=gcc
法二: 在 configue 之后,將 bjam 文件拷貝到 boost 主目錄下,執(zhí)行 ./bjam 調(diào)用 build system ,指定 編譯工具 來安裝,比如說, GNU/GCC 。 bjam "-sTOOLS=gcc" install 如果你只打算生成庫 并且把編譯好的庫收集到一個(gè)文件夾里面而不打算安裝它們。 bjam "-sTOOLS=gcc" stage
bjam [options...] [install|stage]
./bjam -sPYTHON_ROOT=/usr -sPYTHON_VERSION=2.3 -sTOOLS=gcc --builddir=Build stage 只生成庫,并不安裝。 ./bjam -sPYTHON_ROOT=/usr -sPYTHON_VERSION=2.3 -sTOOLS=gcc --builddir=Build 安裝在默認(rèn)路徑下,中間文件放在 Build 文件夾下。 注意:安裝過程會(huì)自動(dòng)獲取 Python 的版本,沒有需要自己填寫版本。兩外 regex 庫的安裝需要 Unicode/ICU ,如果沒有安裝,會(huì)自動(dòng)跳過,可忽略。 編譯的時(shí)間比較長,大約需要 45 分鐘 。 編譯結(jié)果:生成相關(guān)的庫文件。有 date_time , filesystem , iostreams , program_options , python , regex , serialization , signals , test , thread , wave 等庫文件,這些庫和系統(tǒng)相關(guān),并非完全模板實(shí)現(xiàn)。
文件結(jié)構(gòu)( boost 源代碼目錄)boost ---- boost 的源代碼目錄,也就是核心功能代碼,基本上都是模板實(shí)現(xiàn)! libs ---- boost 相應(yīng)庫的使用范例和測(cè)試代碼。從使用 boost 的角度看,有很高的參考價(jià)值! Tools ---- 和 boost 庫相關(guān)的工具,比如 build 工具??梢圆豢础?/span> Doc/more/people/wiki 等目錄,含有和 boost 相關(guān)的信息,如使用說明( XML 格式),作者信息等。沒必要看。
Bind 庫學(xué)習(xí)( ~/libs/bind/test/ bind_test.cpp 是一個(gè)很好的參考。) Bind 庫用于創(chuàng)建綁定到函數(shù)(自由函數(shù)或成員函數(shù))的函數(shù)對(duì)象 ,也可以綁定類的成員變量。 參數(shù):可以直接為創(chuàng)建的函數(shù)對(duì)象提供參數(shù)(內(nèi)部括號(hào) ),也可以通過 bind 外部括號(hào)提供參數(shù) ,再使用 bind 的占位符間接給生成的函數(shù)對(duì)象提供參數(shù)。唯一需要保證的就是,提供給函數(shù)對(duì)象的參數(shù)必須和該函數(shù)的參數(shù)個(gè)數(shù)和類型一致(內(nèi)部括號(hào));通過外部括號(hào)傳遞的參數(shù)沒有什么限制,但是這些參數(shù)的位置和占位符 1_,2_ 等有對(duì)應(yīng)關(guān)系。 生成函數(shù)對(duì)象的返回值:對(duì)于綁定自由函數(shù)和成員函數(shù), bind 庫可以自動(dòng)推斷函數(shù)的返回值,但是對(duì)于綁定函數(shù)對(duì)象,需要指定返回值,使用 bind<type>( ). 使用舉例: 綁定自由函數(shù): #include <boost/bind.hpp> #include <boost/ref.hpp> using namespace boost;
long f_1(long a) { return a; }
long f_2(long a, long b) { return a + 10 * b; }
int const i = 1; BOOST_TEST( bind(f_1, _1)(i) == 1L ); // 通過占位符提供參數(shù) BOOST_TEST( bind(f_2, _1, 2 )(i) == 21L ); // 通過占位符提供參數(shù),直接提供參數(shù)
綁定成員變量(包括虛函數(shù)): bind 表達(dá)式的第一個(gè)參數(shù)必須是成員函數(shù)對(duì)應(yīng)類的一個(gè)實(shí)例。因?yàn)轭愂遣痪哂械刂返?,只要類?shí)例才有,綁定是依賴于地址的。 struct X { mutable unsigned int hash; X(): hash(0) {}
int f0() { f1(17); return 0; } int g0() const { g1(17); return 0; }
int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; } int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; } } // 1 X x; // 類實(shí)例,賦予成員函數(shù)和成員變量的地址,用于綁定。 bind(&X::f1, &x, 1)(); bind(&X::f1, ref(x), 1)();
bind(&X::g1, &x, 1)(); // 使用對(duì)象指針,拷貝指針而已 bind(&X::g1, x, 1)(); // 使用值傳遞,會(huì)引起對(duì)象拷貝 bind(&X::g1, ref(x), 1)(); // 使用對(duì)象引用,可以避免復(fù)制 bind(&X::g1,cref(x), 1)(); // 使用對(duì)象 const 引用,可以避免復(fù)制 // 傳遞對(duì)象的值會(huì)產(chǎn)生拷貝,從而不用考慮原先對(duì)象的生存期,但是為引起性能消耗;可以通過傳遞指針,或者顯式指定傳遞引用 (ref()/cref()) 來避免對(duì)象拷貝。這條準(zhǔn)則也使用于需要以對(duì)象作為參數(shù)的 lambda 表達(dá)式等。
綁定函數(shù)對(duì)象 struct Y { short operator()(short & r) const { return ++r; } int operator()(int a, int b) const { return a + 10 * b; } long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; } void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; } };
void function_object_test() { using namespace boost; short i(6); int const k = 3;
BOOST_TEST( bind<short> (Y(), ref(i) )() == 7 ); // 傳遞變量 i 的引用 BOOST_TEST( bind<short>(Y(), ref(i))() == 8 ); BOOST_TEST( bind<int>(Y(), i, _1)(k) == 38 ); BOOST_TEST( bind<long>(Y(), i, _1, 9)(k) == 938 ); } /// 綁定適配的函數(shù)對(duì)象,需要定義 result_type 來完成類型推斷( 返回值)。 struct Z { typedef int result_type; // 關(guān)鍵點(diǎn) int operator()(int a, int b) const { return a + 10 * b; } };
void adaptable_function_object_test() { BOOST_TEST( boost::bind(Z(), 7, 4)() == 47 ); }
組合綁定:內(nèi)層綁定先求值,所得的返回值作為外層 bind 生成函數(shù)對(duì)象的參數(shù)。 int const x = 1; int const y = 2; BOOST_TEST( bind(f_1, bind(f_1, _1))(x) == 1L ); BOOST_TEST( bind(f_1, bind(f_2, _1, _2))(x, y) == 21L ); BOOST_TEST( bind(f_2, bind(f_1, _1), bind(f_1, _1))(x) == 11L ); BOOST_TEST( bind(f_2, bind(f_1, _1), bind(f_1, _2))(x, y) == 21L );
Lambda 庫學(xué)習(xí)Lambda 庫能夠創(chuàng)建可以直接定義和調(diào)用的函數(shù)對(duì)象 ,或者把函數(shù)對(duì)象存儲(chǔ)起來以便于后續(xù)調(diào)用。即在調(diào)用點(diǎn)定義未命名函數(shù)。其功能涵蓋 bind 庫。 Lambda 的 bind 功能和 bind 庫功能基本一樣 ,不再贅述。 創(chuàng)建 Lambda 表達(dá)式時(shí)沒有關(guān)鍵字或者名稱,由占位符表示這里是一個(gè) lambda 表達(dá)式。 如果要使常量編程 lambda 表達(dá)式的一部分,需要使用 constant 關(guān)鍵字。
基本用法 lambda 支持所有內(nèi)置類型的運(yùn)算,運(yùn)算規(guī)則不變,同原先的算術(shù)、邏輯、移位、比較等操作。 boost::function<int (int, int)> f; // 定義一個(gè)回調(diào)函數(shù) f = _1 + _2; // 定義一個(gè) lambda 函數(shù)對(duì)象,并存儲(chǔ)在 f 中 BOOST_CHECK(f(1, 2)== 3); // 使用 lambda 函數(shù)
int i = 1; int j = 2; int k = 3; using namespace std; using namespace boost::lambda; BOOST_CHECK((_1 + 1)(i)==2); // 對(duì)表達(dá)式求值,不改變變量值 BOOST_CHECK(((_1 + 1) * _2)(i, j)==4); BOOST_CHECK((_1 - 1)(i)==0);
i = 1; (i += _1)(make_const(1)); // 對(duì)表達(dá)式求值,并賦值給變量 i BOOST_CHECK(i == 2);
bool t = true, f = false; BOOST_CHECK((_1 && _2)(t, t) == true); // 對(duì)表達(dá)式求值
int i = 0; BOOST_CHECK(_1++(i) == 0); // 變量 i 的自家運(yùn)算 BOOST_CHECK(i == 1);
常見用途: 1 無需 <functional> 的算術(shù)運(yùn)算; 2 編寫可讀的謂詞 std::vector<int> vec; ……………. std::for_each(vec.begin(), vec.end(), _1+=10); // 算術(shù)運(yùn)算 std::for_each(vec.begin(), vec.end(), _1*=2);
std::find_if(vec.begin(), vec.end(), (_1>3 && _1<10) || _1<1); std::find_if(vec.begin(), vec.end(), _1>=4 && _1<10); // 可讀謂詞
lambda 的 Bind 功能同 bind 庫,此外, lambda 庫還具有控制結(jié)構(gòu),轉(zhuǎn)型、構(gòu)造和析構(gòu)、異常等不常用的功能,需要時(shí)參考 libs 中的相關(guān)代碼和例子。
Function 庫學(xué)習(xí)Function 主要用于為后續(xù)的調(diào)用存儲(chǔ)函數(shù)的指針和函數(shù)對(duì)象。傳統(tǒng)上,函數(shù)指針 用于實(shí)現(xiàn)回調(diào)函數(shù)和延遲函數(shù) , Function 庫采用范型機(jī)制來定義所要存儲(chǔ)的函數(shù)的簽名 ,而讓調(diào)用者來決定提供哪一種類型的類函數(shù)實(shí)體 (函數(shù)指針或函數(shù)對(duì)象)。因此 Function 可以完全實(shí)現(xiàn)函數(shù)指針?biāo)艿墓δ?,并可以給存儲(chǔ)的函數(shù)增加狀態(tài) (一般函數(shù)是沒有狀態(tài)的,但是函數(shù)對(duì)象本質(zhì)是類,故可以存儲(chǔ)對(duì)象)。(定義了: return_type operator() ( 參數(shù) ) 的類,即為函數(shù)對(duì)象。 )
基本功能: #include <iostream> #include “boost/function.hpp”
bool some_func(int i, double d) { return i>d; }
int main(){ boost::function<bool (int, double) > f; // 聲明 f = &some_func; // 一般使用函數(shù)指針,默認(rèn)函數(shù)名也是函數(shù)指針 f(10,1.1); // 延遲調(diào)用,或者回調(diào) }
struct write_five_obj { void operator()() const { global_int = 5; } }; typedef function<void ()> func_void_type; // 必須和函數(shù)對(duì)象的 operator 對(duì)應(yīng)。
write_five_obj five; func_void_type v1; BOOST_CHECK(v1.empty()); // Assignment to an empty function v1 = five; // 使用函數(shù)對(duì)象,會(huì)產(chǎn)生拷貝 BOOST_CHECK(v1 != 0); // 存儲(chǔ)類成員函數(shù), function 的第一個(gè)參數(shù)必須為類的實(shí)例 。原因同 bind , function 本質(zhì)上依賴于函數(shù)的地址,只要類的實(shí)例才有地址,因此必須將所要存儲(chǔ)的類成員函數(shù)的所在實(shí)例傳遞給 function 變量。 struct X { X(int v) : value(v) {}
int twice() const { return 2*value; } int plus(int v) { return value + v; }
int value; };
static void test_member_functions() { boost::function<int (X*)> f1(&X::twice);
X one(1); X five(5); BOOST_CHECK(f1(&one) == 2); BOOST_CHECK(f1(&five) == 10);
boost::function<int (X*)> f1_2; f1_2 = &X::twice; BOOST_CHECK(f1_2(&one) == 2); BOOST_CHECK(f1_2(&five) == 10);
boost::function<int (X&, int)> f2(&X::plus); BOOST_CHECK(f2(one, 3) == 4); BOOST_CHECK(f2(five, 4) == 9); }
Signals 庫學(xué)習(xí)Signals 庫具體化信號(hào)( signal )和插槽( slot ),信號(hào)指的是某種可以“發(fā)射”的東西,而插槽指的是接收信號(hào)的連接。這是一種著名的設(shè)計(jì)模式,稱為觀察著、信號(hào) / 插槽,發(fā)布者 / 訂閱者、事件等。該設(shè)計(jì)模式常常用于代碼的解耦。 注意: 1. signal 永遠(yuǎn)不能復(fù)制。因此包含 signal 的類必須手動(dòng)編寫復(fù)制構(gòu)造函數(shù)和復(fù)制運(yùn)算符。 2. 屬于同一個(gè)組的插槽會(huì)以不確定的順序執(zhí)行,如果插槽的調(diào)用順序事關(guān)緊要,就必須把插槽放入不同的組中。 3. signal 類模板擁有一個(gè)名為 Combiner 參數(shù)后類型,它就是負(fù)責(zé)組合并返回結(jié)果的類型。默認(rèn)返回所調(diào)用的最后一個(gè)插槽的返回值。但是可以通過自定義的 Combiner 的函數(shù)對(duì)象來組合返回值。 4. boost::signal::connect 會(huì)返回一個(gè) boost::signals::connection 的實(shí)例。通過使用這個(gè) connection 對(duì)戲那個(gè)可以將插槽和 signal 斷開,還可以測(cè)試插槽是否已經(jīng)連接到 signal 。 Connection 是 signal 和插槽之間的實(shí)際鏈接句柄。
Signal 庫的使用:定義一個(gè) signal 對(duì)象,聲明同 function 。定義自由函數(shù)或者函數(shù)對(duì)象。函數(shù)簽名同 signal 所聲明的格式。在這樣的基礎(chǔ)上,就可以將自由函數(shù)指針、函數(shù)對(duì)象、 bind 表達(dá)式或者 lambda 表達(dá)式作為插槽 同 signal 對(duì)象相連使用 connect 方法,建立插槽和信號(hào)的關(guān)聯(lián)。 connect 可以對(duì)插槽分組 ,確定插槽的調(diào)用順序。之后只要,調(diào)用 signal 對(duì)象的 operator()(T1,T2,T3,…,TN) 方法發(fā)射信號(hào) ,相關(guān)聯(lián)的插槽就會(huì)被回調(diào)。傳遞給插槽的參數(shù)通過 operator() 傳遞 。
如何將 signals 庫用于類之間的通訊。將 signal 對(duì)象作為某個(gè)類的成員變量 ,并對(duì)外提供建立鏈接的接口。作為插槽使用的類,應(yīng)該定義為函數(shù)對(duì)象,即定義 operator() 接口 。使用中,只要觸發(fā) signal 對(duì)象發(fā)送信號(hào),相應(yīng)插槽類的 operator() 接口將會(huì)被調(diào)用。 g++ -o test doc_view.cpp -lboost_signals-gcc-d
舉例: #include <boost/bind.hpp> #include <boost/signals/signal1.hpp> #include <iostream>
struct print_string : public boost::signals::trackable { typedef void result_type; void print(const std::string& s) const { std::cout << s << std::endl; } };
struct my_button { typedef boost::signal1<void, const std::string&> click_signal_type; typedef click_signal_type::slot_type click_slot_type;
boost::signals::connection on_click_connect(const click_slot_type& s) { return on_click.connect(s); }
my_button(const std::string& l) : label(l) {}
virtual ~my_button() {}
void click();
protected: virtual void clicked() { on_click(label); }
private: std::string label; click_signal_type on_click; };
void my_button::click() { clicked(); }
int main() { my_button* b = new my_button("OK!"); print_string* ps = new print_string(); b->on_click_connect(boost::bind(&print_string::print, ps, _1)); // 使用 bind 表達(dá)式作為插槽。
b->click(); // prints OK! delete ps; b->click(); // prints nothing return 0; }
上述四個(gè)庫之間的聯(lián)系: lambda 表達(dá)式用于生成臨時(shí)的函數(shù)對(duì)象,也稱未命名函數(shù)。 Bind 是 lambda 的功能子集,同樣可以生成函數(shù)對(duì)象,但是不能僅僅通過占位符來生成臨時(shí)函數(shù)對(duì)象,需要依賴于現(xiàn)有的函數(shù)指針、類(成員變量、成員函數(shù))才能生成函數(shù)對(duì)象。 Function 用于存儲(chǔ)函數(shù)指針和函數(shù)對(duì)象,用于后續(xù)的調(diào)用,同時(shí)屏蔽函數(shù)指針和函數(shù)對(duì)象間的區(qū)別,更好的支持范型編程。 Signal 是一種特定設(shè)計(jì)模式的實(shí)現(xiàn),更好的解除代碼(類)之間的耦合關(guān)系。 Signal 通過聲明是采用的函數(shù)簽名,即可以使用 connect 方法將滿足簽名條件的函數(shù)指針、函數(shù)對(duì)象、 bind 表達(dá)式或 lambda 表達(dá)式作為插槽與信號(hào)對(duì)象關(guān)聯(lián)。 總得來說,這四個(gè)類都和函數(shù)指針和函數(shù)對(duì)象有關(guān),因此都依賴于于對(duì)象實(shí)際的地址。由于函數(shù)對(duì)象本質(zhì)是類的實(shí)例,具有狀態(tài),因此相當(dāng)于在函數(shù)中保存狀態(tài),這在很多時(shí)候有用。其中 bind 表達(dá)式和 lambda 表達(dá)式都是產(chǎn)生函數(shù)對(duì)象,只是該函數(shù)對(duì)象事先沒有聲明而已,這在使用 STL 的算法時(shí)非常有用,可以簡化代碼,提高可讀性。由于 bind 表達(dá)式和 lambda 表達(dá)式本質(zhì)就是臨時(shí)的函數(shù)對(duì)象,因此也可以在 Function 和 signal 中使用。
智能指針 shared_ptr boost 的 shared_ptr 是一個(gè)引用計(jì)數(shù)的智能指針,提供了比 auto_ptr 更好的功能,允許多個(gè)客戶之間共享對(duì)象??捎迷谙旅媲樾沃校?/span> 1. 當(dāng)對(duì)象擁有多個(gè)客戶,但沒用明確的擁有者時(shí); 2. 當(dāng)在標(biāo)準(zhǔn)庫容器中存儲(chǔ)指針時(shí); 3. 當(dāng)在庫之間來回傳遞對(duì)象而沒有表明所有權(quán)時(shí); 4. 當(dāng)管理一些需要特殊清楚操作(自定義刪除工具)的資源時(shí)。
Conversion 庫 polymorphic_cast 用于多態(tài)轉(zhuǎn)換,并且不管是對(duì)引用類型還是對(duì)指針類型進(jìn)行轉(zhuǎn)換時(shí)只要轉(zhuǎn)換失敗,都會(huì)拋異常。對(duì)于 STL 的 dynamic_cast ,如果轉(zhuǎn)換引用類型,那么會(huì)通過拋異常來報(bào)告轉(zhuǎn)換失??;如果轉(zhuǎn)換指針類型,則是通過返回空指針來報(bào)告轉(zhuǎn)換失敗。它們都可以用于從基類向派生類的向下轉(zhuǎn)型和交叉轉(zhuǎn)型 (crosscast) ,即從一個(gè)基類到另一個(gè)基類的轉(zhuǎn)型(多繼承情況)。 polymorphic_cas 行為一致,比較不容易出錯(cuò)。 Polymorphic_downcast 是 static_cast 的替代版本,因?yàn)?/span> polymorphic_cas 在調(diào)式狀態(tài)下使用 dynamic_cast 來測(cè)試是否失敗。在發(fā)布模式下,兩者都是很不安全的。因?yàn)閮烧叨际莾H僅執(zhí)行所需的指針?biāo)阈g(shù)運(yùn)算,而把保證轉(zhuǎn)換有效的責(zé)任留給程序員,轉(zhuǎn)換永遠(yuǎn)不會(huì)出錯(cuò),但卻不保證轉(zhuǎn)換后的指針有效(段錯(cuò)誤)。最好不用! numeric_cast 函數(shù)提供了算術(shù)類型之間的高效的、進(jìn)行范圍檢查的轉(zhuǎn)換??捎糜谝韵虑闆r: 1. 需要進(jìn)行無符號(hào)和又符合類型之間的賦值或比較時(shí); 2. 需要進(jìn)行不同大小的整數(shù)類型之間的賦值或比較時(shí); 建議不要使用,因?yàn)樽詈玫姆椒ň褪遣灰D(zhuǎn)換! Lexical_cast 函數(shù) 是一個(gè)用于字符串類型 到其他類型 之間的進(jìn)行詞法轉(zhuǎn)換的可重用的而且高效的工具。使用 Lexical_cast 函數(shù)的動(dòng)機(jī)有以下幾種情況: 1. 從字符串類型到數(shù)值類型的轉(zhuǎn)換 2. 從數(shù)值類型到字符串類型的轉(zhuǎn)換; 3. 用戶自定義類型所支持的所有的詞法轉(zhuǎn)換。 Lexical_cast 函數(shù)實(shí)現(xiàn)上依賴于 STL::stringstream 函數(shù),因此該函數(shù)可用于任何支持 operator<< 進(jìn)行輸出的源和任何支持 operator>> 進(jìn)行輸入的目標(biāo)。對(duì)于內(nèi)置類型無需改變,對(duì)于用戶定義的類型 (user-defined type, UDT) 則需要子定義 >> 和 << 操作,比如: friend std::ostream operator<<(std::ostream& o, const Type& t); friend std::istream operator>>(std::istream& i, Type& t);
Utility 庫學(xué)習(xí) 提供編譯時(shí)斷言 BOOST_STATIC_ASSERT ,當(dāng)然條件必須編譯時(shí)可知,如編譯常量和類型信息, sizeof 函數(shù)。常用于范型編程。 提供安全的析構(gòu)函數(shù) checked_delete 和 checked_array_delete 。判斷析構(gòu)函數(shù)是否完整。 提供禁止復(fù)制類 noncopyable ,繼承該類的派生類不能被賦值和復(fù)制。簡化對(duì)類的復(fù)制構(gòu)造函數(shù)和復(fù)制賦值運(yùn)算符的禁止代碼編寫。 提供 addressof 函數(shù)獲取任何對(duì)象的真實(shí)地址,即使重載了 operator& 。防止惡意重載。 通過 enable_if 和 disable_if 控制重載和特化的參與。也可用于范型編程。
Operators 庫學(xué)習(xí) 為用戶自定義的類提供一組關(guān)系正確的關(guān)系運(yùn)算符和算術(shù)運(yùn)算符是很重要的,在使用某些 STL 算法是還是必須的。 Operators 提供相應(yīng)功能,看大大簡化該任務(wù),并更好的保證正確性和對(duì)稱性。在決定為類增加運(yùn)算符是一定要深思熟慮,但是一旦決定了要為類增加運(yùn)算符,則應(yīng)盡可能使用 operators 庫。
Regex 庫學(xué)習(xí) Regex 庫為 C++ 提供正則表達(dá)式的支持,將被納入 STL ,主要用于文本處理和驗(yàn)證輸入。 Boost/regex.hpp Typedef basic_regex<char> regex; // 類似 string 類 Typedef basic_regex<wchar> wregex; 從某種意義上來說, regex 是一個(gè)特殊類型的字符串的容器,表示特定的字符串模式。 用于 regex 類的自由函數(shù): regex_match/regex_search/regex_replace. regex_match 用于判斷正則表達(dá)式是否完全匹配整個(gè)字符串序列。 regex_search 在字符串序列中查找匹配正則表達(dá)式的子序列。 regex_replace 用特定的子序列替換匹配正則表達(dá)式的子序列。
參考 ~/libs/reges/ 學(xué)習(xí)。對(duì)于 regex 表達(dá)式的語法,可以參考《精通正則表達(dá)式 3 》。
Any 庫學(xué)習(xí) 一般類型安全可以防止犯錯(cuò),并且改善代碼的性能,應(yīng)該盡可能避免使用無差別類型。但是如果需要異構(gòu)存儲(chǔ)、需要將使用者與類型的細(xì)節(jié)隔離、或者需要在較低的層次獲得最大的靈活性,那么可以考慮使用 any 庫。該庫可以對(duì)任意的類型提供類型安全的存儲(chǔ)和安全的檢索;提供了在標(biāo)準(zhǔn)庫容器中存放異構(gòu)類型的方法(使用 any 類型);傳遞類型所通過的層無須了解任何該類型的信息。 自由函數(shù): any_cast 和 dynamic_cast 一樣 ,對(duì)引用轉(zhuǎn)型會(huì)拋異常報(bào)錯(cuò);對(duì)指針轉(zhuǎn)型則通過返回空指針報(bào)錯(cuò)。 boost::any a; a=std::string(“agadgadh”); a= 42; a= 3.1416; std::string s = boost::any_cast<std::string>(a); // throw bad_any_cast double i = boost::any_cast<double>(a); // 返回正確值 int * k = boost::any_cast<int>(a); // 返回空指針 |
|