Category Archives: C++ Language

One Definition Rule – class type

最近在幫忙debug看到一段有意思的程式碼 我把出問題程式核心概念抽出來碼簡化改寫如下 以上程式碼在VC++2015環境下執行 class2.cpp dynamic_cast fail! 如果單純只看class2.cpp ClassC2* p2 = dynamic_cast(p.get()); std::cout << “Class2 ” << p2 << std::endl; 看起來沒有什麼問題,shared_ptr<Class2C1> p 被assign new ClassC2 , 再取出來做dynamic_cast轉回ClassC2 dynamic_cast失敗所以return nullptr,但是shared_ptr p 裡頭存的不是ClassC2 pointer嗎? 應該要能夠down cast成功 如果仔細看,會發現ClassC2同時在class1.cpp, class2.cpp被定義了! 為什麼compile時沒報任何錯呢? 例如redefinition,原因是compile是針對translation unit,在同一個translation unit不能有重複定義,但是在不同的translation unit,標準允許可以重複定義(class … Continue reading

Posted in C++ Language | Leave a comment

return 0 for std::string type

看到一段有問題的code,簡化如下 這樣子會compile過嗎? 答案是可以,此範例是可以通過compile。但是0是integer,integer和string應該不相容吧? 的確是不相容,其他的integer會compile不過,剛好 0 例外,在 C++11 4.10描述了 null pointer constant可以被轉成 null pointer 答案是可以,原因就在 std::string 接收 implicit construct from char pointer A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or … Continue reading

Posted in C++ Language | Leave a comment

stringstream使用

寫一個parser簡單的parse input,可以利用stringstream簡單做tokenizer 上面這個寫法看起來沒問題,檢查stringstream的state,如果fail就跳出迴圈,但其實這個寫法並不完全安全 我們再來看另一個範例 一般可能會預期就是印出1, 2, 3, 4, 5, 6的ascii int,但其實還多了一個-1 ,也就是說,在讀完6之後ss 的state還不是eof,等到做了peek()操作後,eof bit就會set了 因此在處理stringstream讀取時,此部分要特別小心,不能假設ss valid代表後面的讀操作就 會正確,還需要在讀操作後做一些檢查 以peek來說,C++11標準中描述的行為 int_type peek(); Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After constructing a sentry object, reads but … Continue reading

Posted in C++ Language | Leave a comment

bits/stdc++.h

https://stackoverflow.com/questions/25311011/how-does-include-bits-stdc-h-work-in-c 有時候會看到一些範例使用 特別是在一些competitive programming中使用到,這個header基本上就是把所有的C++ header include進來,不用再特別去個別include 也可參考 https://gcc.gnu.org/onlinedocs/gcc-4.8.5/libstdc++/api/a01235_source.html 看起來省了好多include header的工,不過需要注意的是,這個header不是standard,所以使用上可能會有portable的issue 另可參考 https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h 這邊提出了一些pros and cons

Posted in C++ Language | Leave a comment

boost build with fPIC

在build so檔時如果要static link boost ,出現error message … can not be used when making a shared object; recompile with -fPIC 需要將boost static build加上PIC的參數 ./b2 cxxflags=”-fPIC” link=static install 參考: https://stackoverflow.com/questions/49129115/linking-boost-static-libraries

Posted in C++ Language | Leave a comment

C/C++中macro的ifndef

以下節錄一段icu unicode lib的文件裡的sample 理論上,這類的macro會定義在header file,而一般header file都會有include guard,所以不會重複include那為什麼要在U_CHARSET_IS_UTF8再檢查一次是否定義過呢? 主要的原因是發生了不在此header定義了這個macro可能來自於其他header,也可能來自於compiler參數例如 g++ … -DU_CHARSET_IS_UTF8=1 這樣就可以透過makefile來做一些動態的macro值改變的處理

Posted in C++ Language | Leave a comment

避免function argument implicit conversion的方式

在std::string中,如果我們想要assign char 例如 std::string s = ‘A’; 這樣是不行的 必須要 std::string s(1, ‘A’); std::string的constructor 參考 http://www.cplusplus.com/reference/string/string/string/ 假想我們是string的設計者,加一個 string(char c); 會如何呢? 這樣看起來似乎完美方便,但其實在使用上多出了一些意想不到的情況 例如 std::string s = 123.4; 這樣就會走 string(char c);這條路而可以compile過,理由是Floating-integral conversions An rvalue of a floating point type can be converted to … Continue reading

Posted in C++ Language | Leave a comment

bool conversion test

後記:以下主要是展示template處理explicit bool operator的檢查所用的技巧,但其實真正要做cast檢查這樣檢查太瑣碎也不全面,可以透過std::is_constructible和std::is_convertible來處理,留待之後的文章整理 在C++中如果我們要知道物件轉成bool的值,可以直接用cast operator將型別轉成bool 例如 (bool)10.0 => true 但是像是 這段代碼顯然是無法通過編譯的(invalid cast from type ‘X’ to type ‘bool’),因為X沒有定義bool轉型的函式 假如我們想要設計一個function GetBool 可以檢查物件是否可轉成bool ─ 如果可以轉型就返回轉型的bool value, 如果不能轉型就返回false 因為使用的型別事先未知,所以勢必要使用template,根據使用者呼叫的參數來決定回傳值。因此很直覺的可以想到應該可以這樣做: 但是這樣做有個問題 ─ 那就是前面提到的,有些類別型別不支援bool轉型(沒有實作bool operator) ,必須在compile time要分兩個function,一個是可以轉型的,一個是不能轉型的,可是要讓呼叫者自己分辨傳入的參數顯然不太方便,這時候可以透過template metaprogramming的一些技巧讓compiler在compile time自動推導處理 這邊展示的GetBool作法參考了 gcc libstdc++-v3的is_convertible的概念實作 ─ 透過helper class推導”type” … Continue reading

Posted in C++ Language | Leave a comment

regex lib

在使用c++11 regex時,需要注意在gcc 4.9.0前 regex的實作是c++0x的特別是CentOS預設的gcc版本是4.8.5,此時可改用boost::regex使用以下 參考: https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions

Posted in C++ Language | Leave a comment

function pointer print

#include #include void test() { } int main() { std::cout

Posted in C++ Language | Leave a comment