真神人也。
2007年6月29日 星期五
軟體才是登峰造極的關鍵
最近iPhone很出名,媒體幾乎都不約而同的讚美=.=...但是也有人提出反駁,指明iPhone的一些功能明明不怎麼樣,例如相機畫素不足或是不支援GPS之類的,相較之下台灣宏達電的手機在功能上反而更剩iPhone一籌呢。
但iPhone之所以會那麼受眾人喜愛,卻不是沒有原因的。看過iPhone的實機demo,真的會不禁讚嘆:這種質感,這種流暢度,真的只是一隻手機嗎XD。畫面精美就不用說了,用手指可以控制整個網頁,翻轉90度字會跟著轉,usability實在是達到出神入化的境界了。台灣代工業很強沒錯,但是軟體才是登峰造極的關鍵啊。硬體功能愈來愈強,到了某一個程度以後,能夠脫穎而出得到消費者青睞的,就只有搭配超強軟體的硬體了。
軟體業所擁有的先天優勢應該不用多說了,但這是一條漫長辛苦的路,很少公司願意等那麼久的時間。台灣現在的軟體業大部分只能靠政府案子過活,做的是軟體代工業(代工業比較快獲利,似乎很受台灣老闆喜愛),但是做事方法又不如印度的專業,整個就是毫無前景可言。政府似乎無法提出有效的解決方案,只是不停的發案試著要餵飽這些"軟體公司",但是古有名言,給他魚吃不如教他捕魚,這句話還蠻有道理的=.=。軟體業找不到人才也是原因之一,因為人才都跑去會賺大錢的行業去了,我覺得台灣可以仿照韓國政府的作法,進來遊戲軟體業不用當兵這樣,因為台灣年輕人真的很不喜歡當兵,這樣一定可以找到很多人才的,難怪韓國OLG這麼囂張=.=
但iPhone之所以會那麼受眾人喜愛,卻不是沒有原因的。看過iPhone的實機demo,真的會不禁讚嘆:這種質感,這種流暢度,真的只是一隻手機嗎XD。畫面精美就不用說了,用手指可以控制整個網頁,翻轉90度字會跟著轉,usability實在是達到出神入化的境界了。台灣代工業很強沒錯,但是軟體才是登峰造極的關鍵啊。硬體功能愈來愈強,到了某一個程度以後,能夠脫穎而出得到消費者青睞的,就只有搭配超強軟體的硬體了。
軟體業所擁有的先天優勢應該不用多說了,但這是一條漫長辛苦的路,很少公司願意等那麼久的時間。台灣現在的軟體業大部分只能靠政府案子過活,做的是軟體代工業(代工業比較快獲利,似乎很受台灣老闆喜愛),但是做事方法又不如印度的專業,整個就是毫無前景可言。政府似乎無法提出有效的解決方案,只是不停的發案試著要餵飽這些"軟體公司",但是古有名言,給他魚吃不如教他捕魚,這句話還蠻有道理的=.=。軟體業找不到人才也是原因之一,因為人才都跑去會賺大錢的行業去了,我覺得台灣可以仿照韓國政府的作法,進來遊戲軟體業不用當兵這樣,因為台灣年輕人真的很不喜歡當兵,這樣一定可以找到很多人才的,難怪韓國OLG這麼囂張=.=
2007年6月25日 星期一
Boost Thread
http://www.boost.org/doc/html/thread.html
Boost也提供了跨平台的多執行緒函式庫,該有的都有(R/W mutex還有問題,還沒正式納入),不過跟普通的多執行緒函式庫有點不同
1. 啟動方法
使用pthread的programmer會用以下方法啟動一個 thread
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
start_routine就是thread的進入點,arg是要傳入的參數,因為只能傳一個參數,所以我們通常都是把所有參數擠在一個struct裡面......
Boost Thread是在建立thread物件時啟動一個執行緒的
boost::thread *mythread = new boost::thread(&threadfunc);
跟 一般不同的是,Boost Thread是接受Boost Function來當作thread的進入點,而不是一般的function pointer而已,上面範例的function pointer只是Boost Function的其中一種type而已, 所以, 我們可以輕鬆做到以下這種事:
直 接把non-static member function當成thread的進入點!!在以前pthread的時代,想要跑non-static member function非常麻煩,通常要寫個static wrapper之類的......拜Boost Function和Boost Bind之賜,這兩者與Boost Thread的完美結合,讓C++ programmer的生活更輕鬆了!!
有人可能已經發現了,Boost Thread在創造thread的時候,沒有地方可以傳參數進去阿!!Well,有了Boost Bind,這根本就不是問題,還能做的比以前更好。
不像以前只能傳void*參數,使用bind想要傳幾個都可以,而且還是type-safe的方式。不過,既然都可以bind member function了,把參數當作member variable的寫法可能比較好
2. Mutex的概念
以前在pthread我們都會這樣來使用mutex
Boost Thread則是把lock當成一個物件,建構出來時表示鎖住一個mutex,解構表示解鎖一個mutex。
由 於lock是stack-allocated的物件,所以在function結束後,lock會自動被摧毀,mutex就會處於unlocked狀態。 Boost Thread的lock都不保證thread-safe,其實它最好應該都被使用在stack裡,thread之間只要share mutex就可以了。
把critical section用括號包起來,然後在最前面創造一個lock,這樣就可以保證這個block的thread-safe了,這樣的寫法比較直覺而且簡潔多了,不會再像以前一樣忘記unlock mutex......
Boost Thread也有一些不足,例如沒有r/w mutex和thread termination。在很多thread lib裡,thread termination通常會牽涉到thread-safe的問題,所以大多數都會有個warning提醒programmer最好不要使用thread termination以避免發生問題(例如memory leak)。事實上,thread termination最好自己在thread裡面implement,才是最保險的作法。
Boost也提供了跨平台的多執行緒函式庫,該有的都有(R/W mutex還有問題,還沒正式納入),不過跟普通的多執行緒函式庫有點不同
1. 啟動方法
使用pthread的programmer會用以下方法啟動一個 thread
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
start_routine就是thread的進入點,arg是要傳入的參數,因為只能傳一個參數,所以我們通常都是把所有參數擠在一個struct裡面......
Boost Thread是在建立thread物件時啟動一個執行緒的
boost::thread *mythread = new boost::thread(&threadfunc);
跟 一般不同的是,Boost Thread是接受Boost Function來當作thread的進入點,而不是一般的function pointer而已,上面範例的function pointer只是Boost Function的其中一種type而已, 所以, 我們可以輕鬆做到以下這種事:
struct MyClass
{
void threadfunc() {// do something}
};
int main()
{
MyClass m;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread...
}
直 接把non-static member function當成thread的進入點!!在以前pthread的時代,想要跑non-static member function非常麻煩,通常要寫個static wrapper之類的......拜Boost Function和Boost Bind之賜,這兩者與Boost Thread的完美結合,讓C++ programmer的生活更輕鬆了!!
有人可能已經發現了,Boost Thread在創造thread的時候,沒有地方可以傳參數進去阿!!Well,有了Boost Bind,這根本就不是問題,還能做的比以前更好。
struct MyClass
{
void threadfunc(int a, double b) {}
};
int main()
{
MyClass m;
boost::thread mythread(
boost::bind(&MyClass::threadfunc, &m, 1, 2.2));
// Wait for the thread
}
不像以前只能傳void*參數,使用bind想要傳幾個都可以,而且還是type-safe的方式。不過,既然都可以bind member function了,把參數當作member variable的寫法可能比較好
struct MyClass
{
void threadfunc() {}
int m_a;
double m_b;
};
int main()
{
MyClass m;
m.m_a = 1;
m.m_b = 2.2;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread
}
2. Mutex的概念
以前在pthread我們都會這樣來使用mutex
// declare mutex
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
void threadfunc(void* param)
pthread_mutex_lock(&m);
// Only one can enter here...
pthread_mutex_unlock(&m);
}
Boost Thread則是把lock當成一個物件,建構出來時表示鎖住一個mutex,解構表示解鎖一個mutex。
// declare mutex
boost::mutex m;
void threadfunc()
boost::mutex::scoped_lock lock(m);
// On exiting this function, the mutex is unlocked
}
由 於lock是stack-allocated的物件,所以在function結束後,lock會自動被摧毀,mutex就會處於unlocked狀態。 Boost Thread的lock都不保證thread-safe,其實它最好應該都被使用在stack裡,thread之間只要share mutex就可以了。
int threadfunc()
{
{
// The first critical section
boost::mutex::scoped_lock lock(m);
// do something
}
{
// The second critical section
boost::mutex::scoped_lock lock(m);
//do something
}
}
把critical section用括號包起來,然後在最前面創造一個lock,這樣就可以保證這個block的thread-safe了,這樣的寫法比較直覺而且簡潔多了,不會再像以前一樣忘記unlock mutex......
Boost Thread也有一些不足,例如沒有r/w mutex和thread termination。在很多thread lib裡,thread termination通常會牽涉到thread-safe的問題,所以大多數都會有個warning提醒programmer最好不要使用thread termination以避免發生問題(例如memory leak)。事實上,thread termination最好自己在thread裡面implement,才是最保險的作法。
2007年6月14日 星期四
Boost program_options
http://www.boost.org/doc/html/program_options.html
Parse command line裡的parameters從來都不是一件簡單的事, 雖然僅僅是字串的解析, 但是沒有一個programmer還想分心去煩惱這些無關緊要的小事, 就像C++的std::string一樣, 簡單有用的設計讓programmer的生活可以輕鬆一點。
使用Java的人應該都對CLI不陌生, 它隸屬於Apache Jakarta Project下的jakarta commons。基本上Boost Program_options做的事情就跟CLI一樣, 所以使用C++的人同樣有方便好用的library可以利用。Java好像比較容易在網路上找到資源, 不管是文件或是程式庫, 都比C++多樣化, 但是Boost出現後慢慢改善了C++的這種情況, 也的確讓很多C++ developer可以更輕鬆的寫程式......離題了
Example:
options_description有overload << 這個operator可以output到std::ostream, 也就是說, 我們可以用cout就能印出那一長串的usage information, 格式排版完全不用擔心, 非常方便。
加入選項, 第一個parameter是參數名稱, 用逗號來區分長選項和短選項, 像第一個就是可以接收--help或-h這種選項。當然也可以在選項裡設定要接受使用者輸入參數, 例如上面的--threads或-t可以讓使用者指定thread的個數。
再來就是parse command line的字串啦, argc跟argv就是那些熟悉的東西, 全部丟進去就好了, 3行code就搞定!!
基本用法大概就是這樣, 真的非常簡單, 以後寫command line程式不用再經歷parsing parameter的痛苦了......
Parse command line裡的parameters從來都不是一件簡單的事, 雖然僅僅是字串的解析, 但是沒有一個programmer還想分心去煩惱這些無關緊要的小事, 就像C++的std::string一樣, 簡單有用的設計讓programmer的生活可以輕鬆一點。
使用Java的人應該都對CLI不陌生, 它隸屬於Apache Jakarta Project下的jakarta commons。基本上Boost Program_options做的事情就跟CLI一樣, 所以使用C++的人同樣有方便好用的library可以利用。Java好像比較容易在網路上找到資源, 不管是文件或是程式庫, 都比C++多樣化, 但是Boost出現後慢慢改善了C++的這種情況, 也的確讓很多C++ developer可以更輕鬆的寫程式......離題了
Example:
namespace po = boost::program_options;
po::options_description desc("Available options");
options_description有overload << 這個operator可以output到std::ostream, 也就是說, 我們可以用cout就能印出那一長串的usage information, 格式排版完全不用擔心, 非常方便。
desc.add_options()
("help,h", "help message")
("server,s", "run as server")
("client,c", po::value<string>(),"run as client and connect to the specified IP")
("bind,b", po::value<string>(), "bind a source IP to the client")
("threads,t", po::value<int>(), "the number of concurrent connections")
;
加入選項, 第一個parameter是參數名稱, 用逗號來區分長選項和短選項, 像第一個就是可以接收--help或-h這種選項。當然也可以在選項裡設定要接受使用者輸入參數, 例如上面的--threads或-t可以讓使用者指定thread的個數。
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
再來就是parse command line的字串啦, argc跟argv就是那些熟悉的東西, 全部丟進去就好了, 3行code就搞定!!
if (vm.count("help"))
{
cout << desc << endl;
return 1;
}
variables_map的count方法可以得知有哪些選項出現, 如果使用者想要看help, 那就用cout直接把options_description印出來就好了。if(vm.count("client"))直接取得剛剛已經宣告好型態的參數, 連atoi或是sprintf這些煩人的雜事都省了......
{
string sip = vm["client"].as<string>();
// connect to server...
}
基本用法大概就是這樣, 真的非常簡單, 以後寫command line程式不用再經歷parsing parameter的痛苦了......
點滑鼠大賽......
http://www.clickclickclick.com/
怎麼會有人這麼北七呢, 這種比賽到底有什麼意義啊XD
我想唯一的意義可能是, 可以看出哪一個國家的人最閒......或是哪一個國家的人用的滑鼠最耐操。台灣現在遠遠落後啊, 愛台灣的台灣人趕快衝啊!!
初步看了一下, 開始比賽前要先輸入圖形文字, 圖形文字是彩色而且是扭曲的, 這樣比較難作弊了。按了大約20下以後, 就會出現加入國家click總和的link, 按下去就可以幫台灣加分數。很奇怪的是, 要加入總和前並不用通過圖形文字的檢查, 這裡的防弊措施僅僅是一個隨機(我猜)的連結而已, 對於精通web robot的人而言, 這應該不是什麼問題才對。因此, 可能可以做出一個robot, 一開始只要輸入圖形文字, 然後就自動按個幾千下加分, 然後再循環, 繼續輸入圖形文字這樣。不過我們不是韓國人, 不可以作弊喔, 科科。
怎麼會有人這麼北七呢, 這種比賽到底有什麼意義啊XD
我想唯一的意義可能是, 可以看出哪一個國家的人最閒......或是哪一個國家的人用的滑鼠最耐操。台灣現在遠遠落後啊, 愛台灣的台灣人趕快衝啊!!
初步看了一下, 開始比賽前要先輸入圖形文字, 圖形文字是彩色而且是扭曲的, 這樣比較難作弊了。按了大約20下以後, 就會出現加入國家click總和的link, 按下去就可以幫台灣加分數。很奇怪的是, 要加入總和前並不用通過圖形文字的檢查, 這裡的防弊措施僅僅是一個隨機(我猜)的連結而已, 對於精通web robot的人而言, 這應該不是什麼問題才對。因此, 可能可以做出一個robot, 一開始只要輸入圖形文字, 然後就自動按個幾千下加分, 然後再循環, 繼續輸入圖形文字這樣。不過我們不是韓國人, 不可以作弊喔, 科科。
2007年6月12日 星期二
Unicode到底是什麼?
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
上面是一篇Joel的文章, 用淺顯易懂的文字說明Unicode的原理。不知道UTF-7, UTF-8, UTF-16, UTF-32嗎?看一下這篇文章吧......還有, wchar_t這個type在UNIX/LINUX上的GCC是4個byte, 在Windows是佔2個byte, programmer一定要注意到這個。
一般來說, unicode的implementation依平台不同, 甚至依compiler而不同, 如果想要避免這種implementation的差異, 可以用現在最portable的unicode支援 - ICU。ICU支援C/C++和Java, .NET好像沒有, 不過.NET有一個System.Text.Encoding, 這個也能支援unicode不同格式之間的互轉。
2007年6月11日 星期一
最近的超級星光大道......
最近楊蹤萎還真紅耶, 把"背叛"唱的比曹格還紅, 曹格不知作何感想......俺是不看這種節目的(碼的唱一首歌就要哭一次, 我會看到想揍人......), 但是在"耳濡目染"之下, 我對那個節目還蠻了解的......囧rz。其實背叛也不錯聽啦, 楊蹤萎唱得也很好, 我也列入我的KTV重點練習曲之一, 科科, 我還想給它改一下歌詞, 唱出來可以更符合我心裡的感慨︰
雨,不停落下來~
bug,怎麼還是在~
儘管我細心design,你要亂掰就亂掰,我一個人,欣賞悲哀~
code,只剩下無奈~
我,一直不願再去改~
程式裡指標之間,永遠都有bug能踩~
只要一改,跑不起來~~
#
緊緊相依的code如何拆分開,你比我清楚還要我說明白~
bug太多會讓人瘋狂的勇敢,我用背叛自己,完成你的喇賽~~~
把code亂改不問一句該不該,當作每週一次對你的交差
破破爛爛慘慘,今後都不管~~
*
只要你能愉快~~~
心,有一句感慨~
我,還能夠跟誰對白~~
在你要豪洨之前,請你再回頭看看~
那些虎爛,還在不在~~~
Repeat #, *
(間奏)
Repeat #, *, *
雨,不停落下來~
bug,怎麼還是在~
儘管我細心design,你要亂掰就亂掰,我一個人,欣賞悲哀~
code,只剩下無奈~
我,一直不願再去改~
程式裡指標之間,永遠都有bug能踩~
只要一改,跑不起來~~
#
緊緊相依的code如何拆分開,你比我清楚還要我說明白~
bug太多會讓人瘋狂的勇敢,我用背叛自己,完成你的喇賽~~~
把code亂改不問一句該不該,當作每週一次對你的交差
破破爛爛慘慘,今後都不管~~
*
只要你能愉快~~~
心,有一句感慨~
我,還能夠跟誰對白~~
在你要豪洨之前,請你再回頭看看~
那些虎爛,還在不在~~~
Repeat #, *
(間奏)
Repeat #, *, *
2007年6月8日 星期五
Visual C++ compile error C2011
因為用到ntohs, ntohl這些function, 所以有include到<winsock2.h>, compile時卻一直出現
'fdset' : 'struct' 型別重複定義
'hostent' : 'struct' 型別重複定義
......
很多類似這種重複定義的問題。有經驗的windows programmer應該會想到, 可能哪邊搞錯同時把<winsock.h>和<winsock2.h> include進來了, 可是search了一下project, 根本就沒有include到什麼<winsock.h>啊, 而且<winsock2.h>的開頭寫著:
#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
有以上的#define, 應該就不會再去include到<winsock.h>裡面的東西了吧!? 應該是這樣沒錯, 除非......你寫成這樣:
#include <winsock.h>
#include <winsock2.h>
<winsock.h>可沒有什麼預防措施以避免include到<winsock2.h>, 所以這樣的排列就會造成<winsock2.h>裡面的定義全部跟<winsock.h>裡面的衝突。但是, 前面說過了, 我沒有include <winsock.h>啊!! 謎底揭曉了, VC的<windows.h>居然include <winsock.h>......, 而且如果include關係像以下這樣, 那一時之間也很難知道發生什麼問題......
myinc.h的內容
#include <windows.h>
...
main.cpp的內容
#include "myinc.h"
#include <winsock2.h>
main.cpp並沒有include <windows.h>, 是它的include file去include到的, 如果include file很多, 找起來會想撞牆......因此, 最好的方法還是以後都把<winsock2.h>擺最上面好了。
'fdset' : 'struct' 型別重複定義
'hostent' : 'struct' 型別重複定義
......
很多類似這種重複定義的問題。有經驗的windows programmer應該會想到, 可能哪邊搞錯同時把<winsock.h>和<winsock2.h> include進來了, 可是search了一下project, 根本就沒有include到什麼<winsock.h>啊, 而且<winsock2.h>的開頭寫著:
#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
有以上的#define, 應該就不會再去include到<winsock.h>裡面的東西了吧!? 應該是這樣沒錯, 除非......你寫成這樣:
#include <winsock.h>
#include <winsock2.h>
<winsock.h>可沒有什麼預防措施以避免include到<winsock2.h>, 所以這樣的排列就會造成<winsock2.h>裡面的定義全部跟<winsock.h>裡面的衝突。但是, 前面說過了, 我沒有include <winsock.h>啊!! 謎底揭曉了, VC的<windows.h>居然include <winsock.h>......, 而且如果include關係像以下這樣, 那一時之間也很難知道發生什麼問題......
myinc.h的內容
#include <windows.h>
...
main.cpp的內容
#include "myinc.h"
#include <winsock2.h>
main.cpp並沒有include <windows.h>, 是它的include file去include到的, 如果include file很多, 找起來會想撞牆......因此, 最好的方法還是以後都把<winsock2.h>擺最上面好了。
2007年6月7日 星期四
Boost shared_ptr
shared_ptr包含於Boost Smart Pointers裡面, 它可以儲存指標, 並保證在所有存取這個指標的shared_ptr被釋放後, 這個指標所指的記憶體會自動被釋放, 這有很多實用的用途, 例如
當然, return一個heap-allocated object是programmer所應該極力避免的, 因為這是造成memory leak的最危險因素, 但是有時候呢, 還是會碰到需要的情況啊, 例如前人寫的程式已經根深蒂固, 根本沒有辦法修改了, 但是又想避免這種memory leak的可能, 這時候shared_ptr就派上用場了!!
雖然到了最後, 我們還是忘記了c的存在, 但是c已經是個shared_ptr而且是local variable, 所以在foo()的最後, c這個變數會從stack裡消失, 而它所包含的指標所指向的記憶體, 也隨著它的消失而自動的被釋放了, 這世界又變的更簡單一點了。而且, 只需要更改到綠色字體部份的code, 其他code完全不受影響, 因為shared_ptr也overload了->這個operator, 所以操作起來就跟操作原來的指標一樣!!
shared_ptr之所以叫shared_ptr, 也是因為可以有多個shared_ptr包含同一個指標囉, 當然, thread-safe它也有gurantee, 在此就不舉例說明了......
class MyClass {...};
MyClass* getMyClass()
{
return new MyClass();
}
void foo()
{
MyClass *c = getMyClass();
c->foo_1();
// ...
// 做了一堆鳥事
// ...
c->foo_n();
// 最後忘記把c這個pointer delete掉, 造成memory leak, 掯!!
}
當然, return一個heap-allocated object是programmer所應該極力避免的, 因為這是造成memory leak的最危險因素, 但是有時候呢, 還是會碰到需要的情況啊, 例如前人寫的程式已經根深蒂固, 根本沒有辦法修改了, 但是又想避免這種memory leak的可能, 這時候shared_ptr就派上用場了!!
class MyClass {...};
shared_ptr<MyClass> getMyClass()
{
return shared_ptr<MyClass>(new MyClass());
}
void foo()
{
shared_ptr<MyClass> c = getMyClass();
// ...
// ...
c->foo_1();
// 做了一堆鳥事
c->foo_n();
// ...
// ...
// 還是忘記c這個變數的存在...囧
}
雖然到了最後, 我們還是忘記了c的存在, 但是c已經是個shared_ptr而且是local variable, 所以在foo()的最後, c這個變數會從stack裡消失, 而它所包含的指標所指向的記憶體, 也隨著它的消失而自動的被釋放了, 這世界又變的更簡單一點了。而且, 只需要更改到綠色字體部份的code, 其他code完全不受影響, 因為shared_ptr也overload了->這個operator, 所以操作起來就跟操作原來的指標一樣!!
shared_ptr之所以叫shared_ptr, 也是因為可以有多個shared_ptr包含同一個指標囉, 當然, thread-safe它也有gurantee, 在此就不舉例說明了......
2007年6月4日 星期一
Boost C++ Library
Boost當初是由C++委員會核心成員所發起的, 到現在已經是非常成熟穩定的程式庫了!!其中已經有10個library被列入C++ Standard TR1裡面, 陸續還有其他library要進入TR2!!
我的感想啊, Boost真的是C++ programmer一直以來夢寐以求的程式庫
小至能夠取代atoi這些小工具的lexical_cast
大至一整個跨平台的filesystem library
(C或C++在不同平台上的檔案處理真的是會讓人想撞牆XD, 有了Boost Filesystem從此就海闊天空了XDD)
都可以在Boost裡面找到
當然還有一些找不到啦, 例如XML和Logging這兩個常用的東西
有志者可以自己寫一套library去加入Boost喔, 不過要經過層層關卡的review, 沒有毅力恆心者請勿嘗試......
我的感想啊, Boost真的是C++ programmer一直以來夢寐以求的程式庫
小至能夠取代atoi這些小工具的lexical_cast
大至一整個跨平台的filesystem library
(C或C++在不同平台上的檔案處理真的是會讓人想撞牆XD, 有了Boost Filesystem從此就海闊天空了XDD)
都可以在Boost裡面找到
當然還有一些找不到啦, 例如XML和Logging這兩個常用的東西
有志者可以自己寫一套library去加入Boost喔, 不過要經過層層關卡的review, 沒有毅力恆心者請勿嘗試......
訂閱:
文章 (Atom)