Re: [問題] foreach實作

看板C_and_CPP作者 (眠月)時間15年前 (2010/10/07 02:28), 編輯推噓15(15010)
留言25則, 14人參與, 最新討論串2/2 (看更多)
試考慮我有一個字串陣列,我要把內容印出來,很簡單。 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)

10/07 02:30, , 1F
XDD
10/07 02:30, 1F

10/07 02:33, , 2F
template真是深奧...
10/07 02:33, 2F

10/07 03:45, , 3F
do ← 保留字喔
10/07 03:45, 3F

10/07 07:13, , 4F
{ ... } while(); 總是令人遺忘XD
10/07 07:13, 4F

10/07 08:46, , 5F
這篇很故意喔...
10/07 08:46, 5F

10/07 09:53, , 6F
關鍵字筆記++謝謝y大
10/07 09:53, 6F

10/07 10:42, , 7F
Push
10/07 10:42, 7F

10/07 10:51, , 8F
完全忘記,打這篇的時候,我還在想說:「奇怪,為什麼別人會把
10/07 10:51, 8F

10/07 10:52, , 9F
函數名稱取做大寫Do,幹麻不直接用 do 就好了,真笨 A_A」
10/07 10:52, 9F

10/07 10:53, , 10F
原來笨的是我 -___________-||
10/07 10:53, 10F

10/07 11:00, , 11F
其實我是從這邊抄來的http://www.filetolink.com/77275ecc
10/07 11:00, 11F

10/07 11:00, , 12F
38頁開始有這種技法的高級應用qq 一個函數就可以用來求所
10/07 11:00, 12F

10/07 11:02, , 13F
有各種種類的point class的 distance.. 不管是 double[2]
10/07 11:02, 13F

10/07 11:02, , 14F
還是 wxPoint, 還是啥你自己定義的 class, double x, y ;
10/07 11:02, 14F

10/07 11:03, , 15F
而且各種維度, 2D, 3D.. 還是三小D 都可以一個函數做掉
10/07 11:03, 15F

10/07 11:07, , 16F
這技巧真有趣
10/07 11:07, 16F

10/07 11:12, , 17F
每次看到template就會有一種"我根本不會C++"的感覺...XDD
10/07 11:12, 17F

10/07 11:16, , 18F
同意超哥
10/07 11:16, 18F

10/07 12:00, , 19F
推!!
10/07 12:00, 19F

10/07 16:49, , 20F
james真是太中肯了(淚推)
10/07 16:49, 20F

10/07 17:11, , 21F
超哥中肯阿!!
10/07 17:11, 21F

10/07 20:54, , 22F
好文章,非常深入~~~~~~~~推!!!
10/07 20:54, 22F

10/07 23:27, , 23F
j大還只有感覺, 小弟我是根本不會XD
10/07 23:27, 23F

10/08 00:02, , 24F
我再也沒臉來C++板了
10/08 00:02, 24F

10/08 01:11, , 25F
h 大...Orz
10/08 01:11, 25F
文章代碼(AID): #1ChB-qJa (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1ChB-qJa (C_and_CPP)