Tag: C++

  • My C++11 async practice

    I’d like to rewrite concurrent.futures.ProcessPoolExecutor.map may be slow in some cases by using C++11 async and future It takes some time to remember C++ stuff, but it’s still fun to write C++ code 🙂 Sample Code Result

  • 以 boost type traits 在 compile time 檢查 function 的 prototype

    在使用 Google C++ Mocking Framework 的時候很可能遇到一個情況,當原本的 virtual function 的 prototype 改變的時候,你所 mocking 的 prototype 很可能不是預期會被呼叫的那個。

  • 一個 boost::exception 的例子

    因為覺得 dprintf 出現的次數實在太多了,我會希望在 exception 就可以包好 __FILE__ 跟 __LINE__,又可以把 std::wstring 包在 exception 一起丟出去,在 catch 的時候再印出來就好。 所以試著寫了這樣一個例子,結果寫的四不像,跟原本想的東西完全部不同了,而且我對於那個 BUFSIZ 相當不滿啊。其實原本希望可以用 ##__VA_ARGS__ 這種 macro 直接吃進來變成一個 boost::any[],然後再想辦法轉成 boost::format 可以用的格式,中間還可以透過 BOOST_FOREACH 來玩的,不過我徹底失敗了,所以最後的成果大家笑笑就好了。

  • 從 inet_ntoa 看 thread safe 的 API

    這周 refactor 一段 code 之後,被同事說:「為什麼 log 的來源 IP 跟目的地 IP 總是一樣呢?」 後來仔細想了一下 inet_ntoa 的 prototype,我就明白了!如果這個 function 不必特意去 free 回傳的 pointer,那可能在內部有一個 static buffer 去保存這個值。果不期然,FreeBSD 的原始碼是這樣實作的 到這邊我們大概就知道,inet_ntoa 並不是一個 thread safe 的 function,你可以用下面這段程式測一下會發生什麼事情。 輸出大概會像 127.0.0.2 => 127.0.0.1 127.0.0.1 => 127.0.0.2 127.0.0.1 => [inet_ntoa error] 127.0.0.2 => 127.0.0.2 所以,直接使用 inet_ntoa 在 reentrant 上可能會發生問題,如果你必須面對這些問題,最好的方式就是使用 inet_ntoa_r 這個 reentrant 的版本,或者直接使用 inet_ntop。 而這難道非得要踩到地雷,或者從…

  • 以 boost::posix_time 處理時間字串

    其實標題並不是那麼準確,這點我們之後再談。 其實起源很簡單,我們常常需要從各式各樣的時間字串轉成 time_t 或者 struct tm,要不然還可能是 FILETIME 跟 SYSTEMTIME 之類的結構。個人覺得 parsing 時間是一件難搞的事情,尤其是當你還要考慮 timezone 的影響,一切都變得不是那麼簡單了。 首先我必須要說,在 Windows 中沒有 strptime(3) 這樣還算好用的東西可以用,所以我又把腦袋動到 boost 上面去了。 我的目標是正確的處理「Sat, 28 Mar 2009 20:18:32 +0800」這樣的字串,然後把他轉成 time_t。我們會分兩個部份處理,首先我們先處理「Sat, 28 Mar 2009 20:18:32」這個部份,因為目前的 %q 只能處理輸出部份,請參考 Date Time Formatter/Parser Objects。 這樣的確很簡單吧,只要按照文件寫的把 format 寫好,boost 就能幫你從 stringstream 的字串轉成 posix_time。 而 timezone 的部份就需要噁心一點的作法了。 我利用 setw 分別把 timezone 的小時與分抓出來,並轉成 time_duration,讓 posix_time…

  • 初探 TR1 function object

    最近的專案常常需要更新 INI 設定檔,而最麻煩的事情莫過於太多零散的設定,你必須要記住 INI 檔設定的 key,再把在某個 object 的 member function 把值抓出來,最後再丟給 WritePrivateProfileString 之類的 function 把值更新進檔案。 所以常常就會寫出一堆噁心的 code 像是。 obj.iniKey = “INI_SERVER”; obj.iniValue = info.GetServer(); UpdateByObj(obj); 這樣的話,有幾個設定就要寫幾次,所有的 Key 跟 Value 的相關性都顯得零散,未來要加上新的設定,也非得要再加上類似的 code 才行……。 忽然我就靈機一動,也許可以用 tr1::function 跟 tr1::bind 來做這樣的事情。 struct proxyConfig { std::string iniKey; std::tr1::function<std::string()> func; }; const proxyConfig configArray [] = { { “INI_SERVER”, std::tr1::bind(&proxyInfo::GetServer, &info)…

  • C++ Format String using boost::format

    如果你只想寫純粹的 C,那你可以忽略這篇的資訊了,因為 sprintf 之類的 function 大概就可以滿足你了。那為什麼還要提到 C++?我想 C++ 的 string 對於程式設計者是美好的,因為我們不用擔心 buffer 到底需要多長,我們可能是無腦的利用 operator += 去操作這個字串,並利用提供的 substring 等 function 快速的開發軟體。 但在我甚少的 C++ 開發經驗中,我總覺得透過 operator += 以及 stringstream 等東西,並沒有辦法像 sprintf 那樣直覺而優雅的將變數置換至字串當中。 就以 Windows 常見的 INI 格式來說,我們如果要輸出一個 AppName,像是 [MyApp],可能的作法是 這似乎比傳統的 sprintf 要顯得複雜的多,也顯得不好閱讀…… 現在你可以考慮 boost::format 讓你寫的 C++ 能有 sprintf 的優雅性,又不必太過於擔心 buffer 的操作。 至於一些 manipulators,與詳細的 formatting 的用法,就請你自己去看一下官方的說明吧。此外,我覺得 python 的…