看板 C_and_CPP 關於我們 聯絡資訊
試考慮我有一個字串陣列,我要把內容印出來,很簡單。 string s[5] ; for (size_t i = 0; i < 5; ++i) { cout << s[i] << endl ; } 若使用 std::for_each 實作的話的話,便是 std::for_each(s, s+5, cout << _1) ; 但是因為你的不是陣列,那就有點小麻煩, 還是可以作到,只是要用到類似 concept map 的 access idiom, 再加上一點點的 template meta-programming。 首先,讓我們寫一個 foreach class, 來作一次列印陣列的動作,只是這次改成是遞迴的方法。 template < int N > // 一般版本 struct foreach { static void do() { foreach<N-1>::do() ; cout << s[N] << endl ; } } ; template <> // 終止條件特化版本 struct foreach<-1> { static void do() {} ; } ; 好,但是這個 foreach 很爛,他只能用在陣列上面, 因為他沒辦法直接套用在我們需要的「異名」成員上, 但是沒關係,我們這個時候加入 access<>() 手法。 他之後就可以用在任何 class 上。 template < int N > // 加了這個 string access(s[]) { return s[N] ; } template < int N > // 一般版本 struct foreach { template < typename T > static void do(T v) { foreach<N-1>::do(v) ; cout << access<N>(v) << endl ; // 改了這個 } } ; 這個版本的 foreach 已經不在乎陣列不陣列了, 他只知道 access,而 access 到底會拿到什麼東西,看的是 access 裡面怎麼實作。 在這個例子裡面,access 會根據傳入的 N 去拿遞 N 個元素。 所以我們現在只要另外針對我們自己的 class 定義 access 的行為就好了。 只要把那些異名的 data member ,對應到不同特化的 access<>() 版本就可以了。 首先讓我們作個簡單的 class 來當作例子, class C { string a, b, c, d, e ; } ; 然後定義這些 access map template < int N > string access(C c) ; template <> string access<0>(C c) { return c.a ; } template <> string access<1>(C c) { return c.b ; } template <> string access<2>(C c) { return c.c ; } template <> string access<3>(C c) { return c.d ; } template <> string access<4>(C c) { return c.e ; } 嘿!這個時候 foreach 竟然就可以用在 C 上面啦~ 太爽啦~撿到一百塊阿~佛舞美男幻阿~ C c ; foreach::do<5>(c) ; 但是以上 code 完全沒有經過編譯跟測試,看看意思就好。 ㄎㄎ -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.113.31 ※ 編輯: yoco315 來自: 118.160.113.31 (10/07 02:29)
loveme00835:XDD 10/07 02:30
purpose:template真是深奧... 10/07 02:33
loveme00835:do ← 保留字喔 10/07 03:45
xatier: { ... } while(); 總是令人遺忘XD 10/07 07:13
ADF:這篇很故意喔... 10/07 08:46
heyshi:關鍵字筆記++謝謝y大 10/07 09:53
elfkiller:Push 10/07 10:42
yoco315:完全忘記,打這篇的時候,我還在想說:「奇怪,為什麼別人會把 10/07 10:51
yoco315:函數名稱取做大寫Do,幹麻不直接用 do 就好了,真笨 A_A」 10/07 10:52
yoco315:原來笨的是我 -___________-|| 10/07 10:53
yoco315:其實我是從這邊抄來的http://www.filetolink.com/77275ecc 10/07 11:00
yoco315:38頁開始有這種技法的高級應用qq 一個函數就可以用來求所 10/07 11:00
yoco315:有各種種類的point class的 distance.. 不管是 double[2] 10/07 11:02
yoco315:還是 wxPoint, 還是啥你自己定義的 class, double x, y ; 10/07 11:02
yoco315:而且各種維度, 2D, 3D.. 還是三小D 都可以一個函數做掉 10/07 11:03
nowar100:這技巧真有趣 10/07 11:07
james732:每次看到template就會有一種"我根本不會C++"的感覺...XDD 10/07 11:12
purpose:同意超哥 10/07 11:16
legendmtg:推!! 10/07 12:00
BlazarArc:james真是太中肯了(淚推) 10/07 16:49
xatier:超哥中肯阿!! 10/07 17:11
goldie:好文章,非常深入~~~~~~~~推!!! 10/07 20:54
VictorTom:j大還只有感覺, 小弟我是根本不會XD 10/07 23:27
hilorrk:我再也沒臉來C++板了 10/08 00:02
loveme00835:h 大...Orz 10/08 01:11