走進Boost Boost 使用入門

2021-04-14 01:40:51 字數 3967 閱讀 2133

4 小結

5 注釋

一直流傳這麼乙個說法,想成為高手,一定要多讀高手寫的源**。哪些**是好材料呢?c++標準庫的源**?不,如果您讀過,就會發現:要麼是各種實現獨有的表達方式讓人摸不著頭腦,要麼是恐怖的**風格(如到處是下劃線)憋得人難受。boost庫的**則相當清晰,注釋合理,命名規範,絕對是適合閱讀的典範。同時,boost內容廣泛,數值計算、泛型程式設計、元程式設計、平台api……不妨從容選擇自己感興趣的部分,細細品味。boost是什麼?一套開放源**、高度可移植的c++庫。

誰發起的?c++標準委員會庫工作組。所以,質量保證,不怕遇到假冒偽劣產品。

有些什麼呢?瞧瞧:

),中文

或http://sourceforge.net/projects/cvsgui/

如果您習慣於傳統cvs的命令列模式,那麼可在admin→command line...→command line settings中輸入下面一行2

cvs -z3 -d:pserver:[email protected]:/cvsroot/boost checkout boost

如果您偏好gui模式,請選擇admin→preferences...,在general的enter cvs root中填寫:

[email protected]:/cvsroot/boost

做到這一步,恭喜您,大部分boost庫就可以用了。

為什麼不是全部?首先,目前還沒有乙個能完全符合c++標準的編譯器,所以boost庫中的元件或多或少不可用,詳細資訊請看boost**上「編譯器支援情況(compiler status)」一文。另外,有些庫需要build相應的lib或dll檔案。不過這樣的庫很少,主要是由於平台相關性的原因,如處理正規表示式的 regex庫、支援python語言的python庫等,而建構庫的過程相當煩瑣,需要使用jam工具(可以簡單提一下:在 tools/build/jam_src/builds目錄下有三個檔案win32-borlandc.mk、win32-gcc.mk、win32- visualc.mk,分別是適用於windows平台下的borland c++ compiler、gnu c++和visual c++的mak檔案。如果在unix平台,則應使用tools/build/makefile。用命令列工具make或nmake來做出jam執行檔案,然後再用jam來建構庫,詳細內容可見boost.build文件)。我個人的建議是,不用急著去建構lib或dll。真的需要使用這些庫時,再make 隨庫提供的mak檔案即可。雖然boost.jam也許是boost庫未來發展的方向,不過畢竟絕大部分庫都無須建構,可以直接使用。

這次我們先挑個簡單實用的boost元件,看看boost能給我們帶來怎樣的便利。

3.1 字串→數值 在csdn論壇上經常看到詢問如何在字串型別和數值型別間進行轉換的問題,也看到了許多不同的答案。下面先討論一下從字串型別到數值型別的轉換。

如何將字串"123"轉換為int型別整數123?答案是,用標準c的庫函式atoi;

如果要轉換為long型別呢?標準c的庫函式atol;

如何將"123.12"轉換為double型別呢?標準c的庫函式atod;

如果要轉換為long double型別呢?標準c的庫函式atold;

……

後來有朋友開始使用標準庫中的string類,問這個如何轉換為數值?有朋友答曰,請先轉換為const char*。我很佩服作答者有數學家的思維:把陌生的問題轉化成熟悉的問題。(曾經有一則笑話,好事者問數學家:知道如何燒水嗎?答:知道。把水壺加滿水,點火燒。又問:如果水壺裡已經有水了呢?答:先倒掉,就轉化為我熟悉的問題了……)

不,不,這樣是c的做法,不是c++。那麼,c++該怎麼做呢?使用boost conversion library所提供的函式lexical_cast(需要引入標頭檔案boost/lexical_cast.hpp)無疑是最簡單方便的。如:

#include

#include

int main()

乙個函式就簡潔地解決了所有的問題。

3.2 數值→字串

那麼從數值型別到字串型別呢?

用itoa?不對吧,標準c/c++裡根本沒有這個函式。即使在windows平台下某些編譯器提供了該函式3

,沒有任何移植性不說,還只能解決int型別(也許其他函式還可以解決long、unsigned long等型別),浮點型別又怎麼辦?當然,辦法還是有,那就是:sprintf。

char s[100];

sprintf(s, "%f", 123.123456);

不知道諸位對c裡的scanf/printf系打印象如何,總之阿炯我肯定記不住那些稀奇古怪的引數,而且如果寫錯了引數,就會得到莫名其妙的輸出結果,除錯起來可就要命了(我更討厭的是字元陣列,空間開100呢,又怕太小裝不下;開100000呢,總覺得太浪費,心裡憋氣,好在c++標準為我們提供了string這樣的字串類)。這時候,lexical_cast就出來幫忙啦。

#include

#include

#include

int main()

跟前面一樣簡單。

3.3 異常

如果轉換失敗,則會有異常bad_lexical_cast丟擲。該異常類是標準異常類bad_cast的子類。

#include

#include

int main()

catch(boost::bad_lexical_cast& e)

cout}

顯然「abcd」並不能轉換為乙個int型別的數值,於是丟擲異常,捕捉後輸出「bad lexical cast: source type value could not be interpreted as target」這樣的資訊。

3.4 注意事項

lexical_cast依賴於字元流std::stringstream(會自動引入標頭檔案

4),其原理相當簡單:把源型別讀入到字元流中,再寫到目標型別中,就大功告成。例如

int d = boost::lexical_cast("123");

就相當於

int d;

std::stringstream s;

s<<"123";

s>>d;

既然是使用了字元流,當然就有些隨之而來的問題,需要特別指出5。

int i = boost::lexical_cast("123.123"); // this will throw

便會丟擲異常。因為「123.123」只能「部分」地轉換為123,不能「完整」地轉換為123.123。

std::string s = boost::lexical_cast(123.1234567);

以上語句預想的結果是得到「123.1234567」,但是實際上我們只會得到「123.123」,因為預設情況下std::stringstream的精度是6(這是c語言程式庫中的「前輩」printf留下的傳統)。這可以說是boost::lexical_cast的乙個bug。怎麼辦呢?權宜之計,可以這麼做:開啟標頭檔案,注意對照修改6:

#include

//...

template

target lexical_cast(source arg)

即可得到正確結果。當然,理論上效率會有一點點損失,不過幾乎可以忽略不計。我們已經體驗了boost::lexcial_cast。當然,lexical_cast不僅僅侷限於字串型別與數值型別之間的轉換:可在任意可輸出到stringstream的型別和任意可從stringstream輸入的型別間轉換。這次的了解儘管很粗略,不過畢竟我們已經「走進boost」,而不僅僅是「走近」。以後,我們可以自行領略boost的動人之處啦。 

Spring Cloud Stream使用入門

前面博文嘗試使用了srping cloudbus,裡面引入了spring cloud starter bus kafka和spring cloud starter bus amqp,實時上它們分別依賴了spring cloud starter stream kafka和spring cloud st...

國美加快推進平台全品類招商入駐 走進溫州招商會

2018年8月27日,國美童裝招商會在溫州舉辦,國美百貨城總經理賈大鵬出席本次活動。會上賈大鵬表示,國美百貨將加大服飾專案一線品牌招商入駐鼓勵,在服飾專案上快速形成大牌集聚陣列,為消費者提供更多優質選擇。對於招商入駐的品牌國美將給予優惠政策強力支援並提供代運營業務,以便解決品牌方線上運營不成熟痛點,...

使用WinDbg除錯SQL Server 入門

這篇文章我想 下sql server裡完全不同的領域 如果使用windbg 來自針對windows的除錯工具 除錯sql server。在我們進入枯澀細節之前,我想詳細解釋下為什麼選擇這樣晦澀的話題來寫這篇文章。在我們進入如何詳細配置windbg對sql serve除錯前,首先我想給你講下sql s...