Re: [問題] foreach實作
試考慮我有一個字串陣列,我要把內容印出來,很簡單。
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
10/07 02:30, 1F
推
10/07 02:33, , 2F
10/07 02:33, 2F
推
10/07 03:45, , 3F
10/07 03:45, 3F
→
10/07 07:13, , 4F
10/07 07:13, 4F
推
10/07 08:46, , 5F
10/07 08:46, 5F
推
10/07 09:53, , 6F
10/07 09:53, 6F
推
10/07 10:42, , 7F
10/07 10:42, 7F
→
10/07 10:51, , 8F
10/07 10:51, 8F
→
10/07 10:52, , 9F
10/07 10:52, 9F
→
10/07 10:53, , 10F
10/07 10:53, 10F
→
10/07 11:00, , 11F
10/07 11:00, 11F
→
10/07 11:00, , 12F
10/07 11:00, 12F
→
10/07 11:02, , 13F
10/07 11:02, 13F
→
10/07 11:02, , 14F
10/07 11:02, 14F
→
10/07 11:03, , 15F
10/07 11:03, 15F
推
10/07 11:07, , 16F
10/07 11:07, 16F
→
10/07 11:12, , 17F
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
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
10/07 23:27, 23F
推
10/08 00:02, , 24F
10/08 00:02, 24F
推
10/08 01:11, , 25F
10/08 01:11, 25F
討論串 (同標題文章)