[心得] 簡介一下boost.preprocessor

作者: loveflames (咕啾咕啾魔法陣)   2017-12-29 12:03:41
以前在板上提過幾次,但沒有多作介紹
這個是為了簡化preprocess-time metaprogramming
一.資料型態
資料型態有四,舉四個範例
#define TUPLE (a,b,c)
#define SEQUENCE (a)(b)(c)
#define ARRAY (3, (a, b, c))
#define LIST (a, (b, (c, BOOST_PP_NIL)))
四種資料型態有各自的元函數,各型態之間可互相轉換
tuple跟sequence我用比較多,所以接下來的範例都使用這兩種資料型態
二.內部參數
在舉範例之前,先來說明幾個內部使用的macro參數,初學者最容易卡在這裡
d:while內部展開使用,下一個可用值
z:repeat內部展開使用,下一個可用值
s:sequence fold內部展開使用,下一個可用值
r:for內部展開使用,下一個可用值
n:repeat內部展開使用,目前迭代值,從0開始計數
在官方網頁會看到一些D、Z、S、R的後綴名稱
呼叫該版本會比較快,但我覺得為了腦細胞著想,不要管這些內部數字
最多寫成間接呼叫(使用macro傳過來的d、z、s、r值)
三.數值計算
BOOST_PP_WHILE(p, op, s)
s是初始狀態,例如一個tuple或sequence
當p為1時以op產生下一個狀態,以此類推,直到p為0為止
http://codepad.org/uhY7ewVU
上面這個是(1,2) -> (2,1) -> (3,0)
四.產生多個類似的code片段
A.條件展開
BOOST_PP_FOR(s, p, op, m)
s是初始狀態,例如一個tuple或sequence
當p為1時展開m,再以op產生下一個狀態,以此類推,直到p為0為止
http://codepad.org/f5bJc2dt
展開成int x2; int x1;
最後狀態為(3,0),故不再展開
B.根據現有資料展開
BOOST_PP_SEQ_FOR_EACH(m, data, seq)
從seq依序取出元素,連同data一起代入m展開
http://codepad.org/ZuJcrnrR
展開成int x1 ; int x2 ;
C.指定展開次數,從0開始依序遞增
BOOST_PP_REPEAT(count, m, data)
展開count次,data代入m展開
這個也可以配合資料型態,依序取出元素
http://codepad.org/bAdBKhUh
展開成int x0 ; int x1 ; int x2 ;
最後提一下,其實還有一種換行展開,不過這裡沒舉出來
作者: Killercat (殺人貓™)   2017-12-29 12:22:00
這在meta-programming真的是很好用的工具,不過我得說這也是我接手的專案裡面,看過最多「為了用而用」的的boost library裡面出現率最高的 XD另外一個類似情形是Signal2...(/facepalm)
作者: loveflames (咕啾咕啾魔法陣)   2017-12-29 12:48:00
因為太炫才為用而用對吧
作者: Killercat (殺人貓™)   2017-12-29 13:08:00
我覺得是 XD 也算是技術宅團隊的特徵啦 (?)

Links booklink

Contact Us: admin [ a t ] ucptt.com