c++ 相關的技術資源整理歸類

twoon發表於2015-10-08

最近一段時間 c++ 社群裡最火熱的話題莫過於 cppcon2015 了, isocpp 上一堆相關的新聞,其中有一個頁面羅列了該會議的全部主題, 匆匆一瞥幾乎眼花繚亂,為期一個星期的會議竟有上百個演講,無論是數量還是內容所覆蓋的範圍,比之去年都更加豐富,作為一個野生的 c++ 的愛好者,我表示這樣的盛會是不容錯過的,多麼希望能有機會前往現場感受一番,門票倒不是太貴,可惜遠隔重洋,只能灑淚遙望。現在 cppcon 已過去一個多星期了,演講的視訊和材料還沒全部公開,isocpp 上說要一個月的時間才能搞好,只能耐心等,目前放出來的只有少數幾個演講,比如,由 Bjarne Stroustrup 和 Herb Sutter 主講的:Writing Good C++14,於是趁著假期虔誠地拜讀一番,給信仰充充值。

突然想起來,去年的 cppcon 也放出了很多演講視訊,我只略看了其中一小部分,當時 c++11 用的還比較少,很多東西都沒接觸,因此有些視訊沒細看,有的沒看懂,現在一年多過去了,很多東西有了很多新的體會,覺得倒是時候回顧一下去年這些人都講了些什麼東西,於是翻啊翻,重看了一些關於網路,併發,型別,模板等相關的演講,收穫很多,這些演講的主題大部分並不是教別人怎麼寫程式碼或介紹新特性之類的,很多是工程實踐中的經驗總結,以及 show off 一下自家的程式設計思想,工具等好東西諸如此類。越來越覺得多關注一下業界的動態,瞭解一下別人在做什麼、怎麼做的,對開闊一個人的思路和眼界實在有莫大的幫助。

只是很多時候很多東西看過就丟開了,再找時東翻西翻,缺少整理就覺得混亂,所以這篇筆記就隨手整理歸類一下近一年多看了些什麼 c++ 相關的東西,記錄記錄,也方便需要時去查詢回顧,僅此而已。


記憶體模型相關的知識

該主題的內容比較難理解也難以使用,特別是當你想寫 lock free code 時。最好的教程我覺得來自於委員會裡這方面權威人士的手筆,比如: Herb Sutter, Hans Boehm, 推薦兩個視訊,都在 msdn chanel9 上:

看完前面兩個視訊,估計就能對 c++11 裡的 threading 和 atomic 相關的庫有大概的瞭解,不過與此同時估計讀者腦海裡也多了一堆對技術細節的疑問,尤其是 ordering 相關的,此時可以再去看看以下兩個長篇,其中一篇是講硬體實現上的細節,a primer on memory consistency and cache coherence,另一篇則介紹了 linux 核心中 memory barrier 的相關知識與背景

如果你實在很好學,追求極致細節想成為 language lawyer 什麼的,這裡幾個連結,分別是 Hans 和 Herb 當初給 c++ 委員會作的原始提案,細看一下就能知道現在 c++11/14 裡相關內容的是怎麼來的:

上面的連結都來自權威人士,其中文章大多非常嚴謹因而可能不夠通俗易懂,國外有一位叫 Jeff Preshing 的遊戲開發者寫了一系列與 memory ordering 相關的博文,他的文章寫的很詳細,每個概念都有長篇的介紹及相關的程式碼,如果你看完 Herb 和 Hans 的那些文章後還是有疑問,那麼可以嘗試再結合一下 Jeff Preshing 的文章來加深一下理解,特別是其中關於 acquire-release, happen-beforesynchronize-with 這幾篇。

最後有一本書介紹給讀者,C++ Concurrency in Action,學以致用,作者也是這方面的先行者 Anthony Williams,他的文章部落格在網上也傳播的很利害,比如 Peterson's algoDeker's algo 在 c++11 中的實現等。


右值引用與型別推導

雖然 BS 諄諄教導不要成為 language lawyer,不要摳太多語言細節,但是。。。不徹底搞懂右值引用又怎麼能夠理解 move 語義,又怎麼能用好新的 STL 呢,更不用說自己寫相關的程式碼了,畢竟語言裡本身有許多 arcane 的細節,弄懂了其實還是有助於少踩坑的,再說了,不能寫 library 的程式設計師也算不得好碼農。

右值引用是一定要搞懂的,推薦兩篇介紹性的長文,其中一篇是 Scott Meyers 寫的 Universal References in C++11, 另一篇則由 Thomas Becker 所寫 C++ Rvalue References Explained,仔細讀完這兩篇文章,應該就能徹底搞懂 move, forward 及其背後那些稀奇古怪的東西。

因為右值引用的出現,c++11 裡對傳參有了一種新的寫法(idiom),叫作 sink parameter,簡單來說就是必要情況下儘可能多地傳值而非傳引用,具體可以看看這篇介紹, 由此也引發了許多對 value semantic 的討論,cpp-next 上有一篇文章值得一讀,want speed? pass by value(連結如果沒法開啟,可以試試這個備份的映象), Sean Parent 有一個 talk: c++ seasoning 也講到了這方面的用法,cppcon2014 裡有也有一個專門的演講是談 value type 的,個人覺得比較有意思。

在學習右值引用的時候,如果你在意細節,相信會遇到一些關於型別推導的疑問(比如 perfect forwarding 裡的模板引數型別推導)。關於型別的推導,比如 auto, decltype 的使用,這裡也有兩篇文件值得一讀,很巧分別還是 Scott Meyers 和 Thomas Becker 所寫,其中一篇是 Scott 在 cppcon2014 上作的演講,Type deduction and why you care, 另一篇則是 Thomas 寫的 C++ auto and decltype Explained,題外話,auto 和 decltype 是 c++11 裡我最喜歡的兩個新特性了,auto 自不必說,隨手 auto 一下強健的右手少敲多少鍵盤,decltype 也是實打實的 productivity booster,以前要寫各種 traits, result of 來人肉推導返回型別的痛苦歲月從此就一去不復返了。至於模板引數的型別推導,個人覺得也是值得仔細研究總結一下的,以後再補充.(TODO)


Threading/concurrency

語言級別的併發程式設計也許是 c++11 眾多的新特性中引入新概念最多的一塊了吧,習慣了從前遠古時代簡單粗暴的多執行緒程式設計模式,到現在滿眼 future, promise, async,恍惚會有錯覺彷彿已經不是在寫 c++,感覺已經變了,味道也變了。確實是變了,變得更加簡單,也變得更加容易,所以最好儘早去嘗試和適應,熟悉了基本的語法和使用規則之後,強烈推薦 Sean Parent 的這個演講,better code: concurrency, 這裡面 Sean Parent 講了一些併發程式設計的基本的準則,best practise 之類的,並且自己重造了一遍 future, promise, packaged_task 等輪子,從而實現了一個簡單版的 async continuation (主要是 then()),Sean 的演講和他的程式一樣一慣地簡練實際,我個人非常地喜歡,也推薦讀者去看看他的 better code 這一系列的演講,乾貨很多。

說到 concurrency,Herb Sutter 也寫了一系列 effective concurrency 的文章,當然一慣地 Herb 的風格了,以說教的形式指出 best practice,如果嫌文章太多太長(我也沒看完),可以看看他的這個濃縮版的演講,該演講把 future, promise, async, then 等方方面面都講到了。個人小小的體會,async 加上 lambda,你會發現 c++ 裡寫 non-blocking code 忽然變得這樣直接和容易,簡直不敢想像。

另外就是關於 coroutine,微軟的人在 cppcon2014 上展示了一個在 vc 中實現的 await2,貌似和 c# 中的 await 有些關聯??從他們的演講來看,await2 可以 stackless,因此 highly scalable, 細節是怎樣的,十分值得細究,基於 await 的程式設計看起來又完全不同的感覺了,很多其它高階語言裡特性逐漸地出現在了 c++ 裡面。


lambda、模板、函式式

lambda 並不是一個新的東西,就算在 c++11 中,它的出現也這樣地順理成章,甚至可以認為不過就是 functor 的語法糖,但是它的誕生在很多情況下卻讓寫程式碼變得這樣的簡單直接,以致如果你深入體驗之後,已經完全沒法再脫離它,前面 Sean Parent 關於 concurrency 的演講裡面就有很多這方面的例子,另一個活生生的例子可以參看一下 Andrei Alexandrescu 的這個演講: systematic error handling in c++,看看 lambda 是怎樣使得 scope guard 在 c++11 裡的實現變得這樣簡潔與實用。說到 scope guard,如能靈活地使用起來,這東西的確在很多時候可以使得程式的控制流更直接更可讀,看看 Andrei 在 cppcon 上的這個演講

對於模板,變長引數的加入極大地簡化了模板超程式設計,以前很多需要使用許多死板的巨集技巧才能實現的功能,現在已經可以很輕鬆地用 variadic template 來實現了, 這裡有一個入門的教程,Andrei Alexandrescu 也在這方面有一個演講(這個題目怎麼少得了他):Variadic Templates are Funadic,Andrei 的演講無論是內容還是風格一如既往讓人傾倒,鼓勵大家前去圍觀。除了變長引數,c++11 中也加入了一系列其它的模板基礎設施,比如更加豐富的 type traits, SFINAE 等,c++ 委員會裡一位資格極老的成員 Walter Brown 在 cppcon2014 上作了一個這方面的演講,不過這裡面主要側重在 SFINAE 了。

說到模板,回想起一年前使用 boost spirit 和 boost proto 所經受的徹底洗禮與摧殘,現在仍覺受益匪淺,我覺得喜歡搞模板的人不嘗試一下 expression template, 不玩一下 proto 那他的人生是不完整的,cpp-next 有 proto 的作者 Eric Niebler 寫的一系列文章:Expressive C++(如果打不開,嘗試這個備份的映象,十分值得一讀,如果讀了一兩遍沒搞懂,沒關係,多看幾遍,你可能會發現還是沒完全搞懂也不奇怪, 看過這一系列文章,如果你還有興趣,cppcon2014 上還有一個更好玩的,HANA: EXPRESSIVE METAPROGRAMMING,enjoy.

最近在 cppcon2014 上發現了一個挺有意思的專案,也是和模板相關的,sqlpp11,這個專案利用 expression template 在 c++11 基礎上實現了一個 sql library,創意程度直逼 boost spirit,關鍵是,它相當地實用,因此實在值得學習借鑑。

最後是關於 functional,是的,functional programming,一聽就高大上,buzzword 火熱如同當紅炸子雞,functional programming via c++ 也許有點牽強,functional programming via c++11,看起來卻有所不一樣了,practical functional programming,看看別人都在想什麼都在玩什麼。。。其實話說回來,這些都不新鮮,boost 庫中相關的庫 fusion 和 phoenix,已經存在很長一段時間了,只是你關注到了沒有而已。


其它未完待續

TODO

相關文章