Re: [語法] Template與Inheritance結合??

作者: CoNsTaR ((const *))   2016-10-24 04:00:51
藉著這串來說一下我對 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
作者: steve1012 (steve)   2016-10-24 05:47:00
看不懂...
作者: soheadsome (師大狗鼻哥)   2016-10-24 10:47:00
學haskell之類的FP就會了解型別推論之類的技術

Links booklink

Contact Us: admin [ a t ] ucptt.com