大山姆的機機車車™ #9
我是山姆,《大山姆的機機車車™》是我的第一份電子報,希望透過這份小報,把我感興趣的資訊分享給同樣求知若渴的您。
本期的主題是一個「古老」的 C++ 技巧-Curiously Recurring Template Patterns (CRTP)。這個技巧不算常用,但學會了,以後使用 C++ 「描述」問題時,是個不錯用的武器。這個技巧常見於[函式,類別]庫的實作,特別是 Header-only Library。
James O. Coplien 於 1995 年提出 CRTP。Mr. Coplien 看過不同人使用類似的手法,有所領悟,將此手法整理成文章解釋這個手法的「迷人」之處。我將該文章 PDF 檔收錄於 Evernote 並載明出處。推薦一讀。
CRTP 是那種看第一眼會被嚇到,心智不健全者可能自我安慰「沒必要搞得這麼複雜」的技巧。這類技巧容易吸引「慣 C 人」嘲諷,遇到時謹記「沒有過於花俏的技術,只有不懂精要的弱魚」,大方「頂」回去!
CRTP 其中一個應用場景是實作 Static Polymorphism,即 Compile-time Polymorphism。有別於 Dynamic Polymorphism(Run-time Polymorphism),Static Polymorphism 的優點之一效能,避免了 Dynamic Dispatch 以及容易 Inline 程式碼,因此常會有顯著的效能提昇(與 Dynamic Polymorphism 相比)。
底下是幾個 C++ 重要觀念,新手越早弄清楚越好:
- Compile-time vs. Run-time
- Class vs. Object
- Value vs. Reference vs. Pointer
- Scope
try { deliverOnTime(); } catch (const std::exception&) { printf("sorry!");}
➫ ➫ ➫ 最近被一個棘手的驅動程式臭蟲搞得心力交瘁,幾乎奮戰了七天七夜,快成「喪屍」還沒把握全身而退。「不怕臭蟲一直來,就怕臭蟲出不來」絕對是軟工最恨排行榜前三。⛈
人物誌
這一期偷個懶,跳過人物觀察...
[caption align="alignnone" width="980"]
這隻是多年前在我車窗外短暫停留的飛行物,虎虎生蜂[/caption]
參兩摘
What the Curiously Recurring Template Pattern can bring to your code - Fluent C++
Fluent C++ 的 Jonathan Boccara 寫了一系列共三篇文章講解 CRTP 的原理與應用。底下是另外二篇:
- What the Curiously Recurring Template Pattern can bring to your code(以範例說明 CRTP 如何應用於日常生活撰碼)
- An Implementation Helper For The Curiously Recurring Template Pattern
Johnathan 的部落格文章品質優良,是近年廣受歡迎的 C++ 部落客,務必訂閱。
The Curiously Recurring Template Pattern in C++
開站近十五年,Eli Bendersky 的文章也是篇篇好看。
ACCU :: Better Encapsulation for the Curiously Recurring Template Pattern
這篇從 Encapsulation(封裝)的角度切入,說明 CRTP 的用途以用法。
Curiously Recurring Template Pattern - YouTube
CRTP is a means to get compile-time polymorphism in C++. Join us as we look at how it works along with a a discussion of complete vs incomplete types
CRTP - Curiously Recurring Template Pattern in C++
速度適中的 CRTP 技巧教學,使用的範例碼容易理解。
CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs at Facebook”
這支影片無關 CRTP,而是臉書工程師列出自家 C++ 程式碼常見的臭蟲。
摘影片
CppCon 2017: Andrew Sutton “Meta”
延續 Herb Sutter 的演講,Andrew Sutton 稱 Reflection 為執行時期轉編譯時期的操作, Inject 為編譯時期插入動態時期的操作。
Andrew 的前一場演講 《CppCon 2017: Andrew Sutton “Reflection”》 展示實作 Reflection 概念的介面適合使用樣板,畢竟 C++ 對於編譯時期決定相當熟悉。
這場演講則展示實作 Inject 適合使用動態連結匿名類的機制,這個匿名類跟 Lambda 有點像,因為 Lambda 本身具備 operator , C++20 擷取子句能使用 this 。
By Sidney Niu
Understanding compiler optimization
編譯器優化最重要的演講肯定是這場,這題目是連續三年的 keynote presentation。
Clang AST 轉成 LLVM IR 之後在優化前首要解決的問題是 Canonicalization,C++ 擁有大量特性導致同樣結果的寫法可以千變萬化,而 Clang 在近年大幅成長也是因為解決了此問題。
最後 IR 轉成控制流程圖,這裡是優化演算法的核心,先優化有向圖的最末端迴圈區,一路解開至進入點,此優化系統方法讓 Clang 成為目前地表最強的 C++ 編譯器。
這些演算法主要跟谷歌大力投入有關,微軟也讓 VS15 高度支援 Clang 。 當初 GCC 從 C 語言換成 C++ 是因為 Ian Lance Taylor 說 C++ 效能與維護性都比 C 好 (Write gcc in C++),但是近年 GNU 很明顯人力吃緊導致實作速度明顯跟不上標準,還被 Ian 說〝FSF is not writing code.〞。
中英對照:控制流程圖(Control Flow Graph)
By Sidney Niu
Handmade Hero Chat 014 - CRTP and Library Design
第一期的人物 Casey Muratori 的《Handmade Hero》系列影片第 014 集,以遊戲開發的角度出發說明 CRTP 的寫法與用法。觀看需要有點基礎,C++ 新手勿入。
[embed https://youtu.be/EhtxDXlrJ6Y?t=24m57s]
開源專案
loguru: A lightweight C++ logging library
每一個不是鬧著玩的軟體專案都需要 Logging,留下程式執行記錄對於「事後」分析與釐清案情非常有用。C++ 的 Logging Library 不少,常見的有 glog, Easyloggin++, spdlog, plog。loguru 是新發現,我在最近新開的專案中使用了這個 Single Header Only library。
常見的 C++ log 語法有兩種,一種函數呼叫,另一種串流型式(Stream)。我比較偏愛串流型式,glog 屬這類。而 loguru 兩種都支援,真討喜。loguru 還內建了 Benchmark 機制,可用來量測某段程式碼的執行效能。
目前 loguru 的文件尚不完整,不過由於是開源專案,使用上有問題應可由原始碼找到解答。
WorkFlowy Tips
[077] WorkFlowy 外掛 WorkFlowy Clipper
除了寫作、記錄點子、以及會議記錄外,WorkFlowy 也是我主要的「瀏覽器書籤」。每次找到一個有趣的網站,我會用 WorkFlowy Clipper 「抓」下來,便於日後使查找。搭配「標籤(Tag)」,搜尋起來很容易。
想知道更多 WorkFlowy 撇步,請快步前往 WorkFlowy Tips 。還沒有 WorkFlowy 帳號?請用此連結申請,加倍免費清單上限。
還有還有,我在臉書開了一個以 WorkFlowy 為主題的社團——山姆的 WorkFlowy 大小撇步現在人很少,快來助拳!
💌 喜歡這一期的內容,請幫我按「👍」。不喜歡請按「👎」,並寫下你認為哪裡做得不好,你的回饋是我進步的動力。想要匿名舉報的話,我開了一個 Sarahah,歡迎使用,謝謝!
本報內含 Affiliate Link 連結若干,也就是我有機會從中獲益,賺點奶粉錢,希望有朝一日能因此日進斗金(誤)。若對這樣的作法有疑慮,請讓我知道或者直接退訂也行,我不會介意,你請別生氣。☯
JUST DO!