看板 C_and_CPP 關於我們 聯絡資訊
藉著這串來說一下我對 C++ template 和相關東西的理解好了 因為 template 好像有很多很神的功能,學都學不完,學完了也不知道在哪邊用(?) 可是 template 其實根本就沒有那麼深奧,都是我們自己把它想得太難了… 怎麼說呢? 我想必須先介紹一個新的概念 —— universe —— 要是我有一些值,例如數字或是字元,而且數字又有正數有負數有整數有小數,字元也分 一般字元和寬字元,而我的任務是負責分類它們,我會怎麼做? T = { x | x ∈ R, INT_MIN <= x <= INT_MAX } 的 T 代表了"一種類型"的值 (例如在 這裡是 int) 講成英文就是 T is "a type of" value 也就是說,T 可以看成是所有 x 的 type 我們可以這樣想: int x ≡ x ∈ int (敘述 int x 相當於 x 屬於 int) 也就是說,types 是由 values 組成的集合,所有的 values 都有 type,而 values 是 types 的 member 因為這些 values 都有一些相同的特徵,它們都滿足特定的條件,所以我把它們歸類成一 個 type 接下來的問題是這樣的,藉由分類 values 我得到了很多的 types 但是我發現很多 type 其實也有共通點,我想再做更高程度的抽象化,再把 types 進行 分類 舉個簡單的例子: Animal = { Bird, Dog, Pig, Cat... } 那我會說,Animal 是"一個種類"的 type 講成英文就是 Animal is "a kind of" type 再舉個實用的例子: Printable = { int, char, double... } (或許有些 type 不能 print 也說不定啊 XD) 我們可以這樣想: template <typename T> struct S {} ≡ S = ∀T. { S<T> } 當然,就像大家想像的,kinds 當然還可以再被歸類,kind 會被歸類成 sort,而 sort 又可以再被歸類成 BOX… 而 value, type, kind, sort, BOX… 這樣的系統就被稱為 universe 上面都懂了以後,最直覺的聯想就是,values 有 function,那 types 有嗎?如果有, 那 kinds 呢? 答案是都有! 為了有個統一的表示法,我先規定一下函數的表示法好了 函數宣告: add_and_ : { a : Num } → a → a → a xxx : xxx 函數名稱 : 型態 底線代表接受參數的地方,不寫就是接在後面 { a : Num } → 代表 a 是 Num 這個 kind 裡的一個 type a → a → a 參數1型態 → 參數2型態 → 回傳型態 函數定義: add a and b = a + b 函數呼叫: add 1 and 2 (答案是3) 我們先來看一個比較容易的例子好了:「pointers」 C/C++ 指標其實不就是 type 的 function 嗎? 如果用一般 function 的方式來理解的話,那指標這個函式應該長類似這樣: _* : typename → typename T* = pointer_of_T 寫成 C++ 的話: typename * (typename T) { return pointer_of_T; } 問題是,C++ 根本不允許我們做這種事情啊… 所以我們就必須要動點頭腦想想,有什麼合法的 C++ 語法能夠表達相同概念的呢? template 或許可以做到: template <typename T> struct * { using type = pointer_of_T; }; "T" 代表傳入的 type,"*<T>::type" 代表回傳 type,"<>::type" 相當於函數呼叫,而 "*" 則是函數名稱 有上面這些概念之後,其實自然而然就會不小心做出 smart pointers 了 XD 我們再來看另一個例子吧:「繼承」 _:_ : typename → typename → typename T : U = U :> T 寫成 C++ 的話: typename : (typename& T, typename U) { // 做一些神奇的魔法,讓 T 擁有所有 U 的成員,或許 T 該被 passed by reference return T; } 所以說,一次繼承很多個 type 該怎麼辦? typename : (typename& T, ...) { // 管你可變參數列裡面是什麼通通繼承就對了 return T; } 當然,實際上 C++ 才不允許我們這樣亂搞勒,不過還是能用 template 做到類似的功能 啦 其實還有很多好玩的東西原本是想在這篇提的,只是看看這篇篇幅已經不短了,所以想想 還是算了吧… 如果你想問有哪個語言有完整的 universe 的觀念,而且這篇裡面提到的所有東西(包括 表示法)通通都支援的,那就是 agda 啦 對了,因為 C++ 的 sort 是 template template,所以要是你下次在寫程式的時候發現 你用了 template template 的話,那就代表你正在用 sort 喔!有沒有很感動的感覺 XD -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.33.205.79 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1477252854.A.31D.html 我覺得自己講得好亂 XD 先睡覺,明天再來整理一下好了 ※ 編輯: CoNsTaR (114.33.205.79), 10/24/2016 04:23:17
steve1012: 看不懂... 10/24 05:47
soheadsome: 學haskell之類的FP就會了解型別推論之類的技術 10/24 10:47