看板 C_and_CPP 關於我們 聯絡資訊
我舉實際一點的例子,比方說取得 max。 我先用爛方法寫出兩個實作品: struct point { int x ; int y ; } ; int max_x ( std::vector<point>& v ) { int result = v[0].x ; for ( std::vector<point>::size_type i = 1; i != v.size(); ++i ) if(v[i].x > result) result = v[i].x ; return result ; } int max_y ( std::vector<point>& v ) { int result = v[0].y ; for ( std::vector<point>::size_type i = 1; i != v.size(); ++i ) if(v[i].y > result) result = v[i].y ; return result ; } std::cout << max_x(v) << std::endl ; std::cout << max_y(v) << std::endl ; 我現在要寫一個通吃兩者的函數,我有兩種作法。 一種是使用「access idiom」 就是我存取 point 的 x 或是 y 的時候,不直接使用 p.x 這種形式, 而是透過一個 access 函數去存取: int& access(point& p, const int index) { return index == 0 ? p.x : p.y ; } int max ( std::vector<point>& v, const int index) { int result = access(v[0], index) ; for ( std::vector<point>::size_type i = 1; i != v.size(); ++i ) if(access(v[i], index) > result) result = access(v[i], index) ; return result ; } std::cout << max(v, 0) << std::endl ; std::cout << max(v, 1) << std::endl ; 更進一步, 為了省去這個 access function 當中 if 的成本, 我們把他改寫成 template 的版本…… template < int N > int& access(point& p) ; template <> int& access<0>(point& p) { return p.x ; } template <> int& access<1>(point& p) { return p.y ; } template < int N > int max ( std::vector<point>& v) { int result = access<N>(v[0]) ; for ( std::vector<point>::size_type i = 1; i != v.size(); ++i ) if(access<N>(v[i]) > result) result = access<N>(v[i]) ; return result ; } std::cout << max<0>(v) << std::endl ; std::cout << max<1>(v) << std::endl ; 另外一個方法,如果不喜歡 specialized 一堆 access 的版本, 我們還有一個 pointer-to-member 的方法可以用,在這邊剛好! int max ( std::vector<point>& v, int point::*m ) { int result = v[0].*m ; for ( std::vector<point>::size_type i = 1; i != v.size(); ++i ) if(v[i].*m > result) result = v[i].*m ; return result ; } std::cout << max(v, &point::x) << std::endl ; std::cout << max(v, &point::y) << std::endl ; 效能的話…… specialized access<>() 最快。 跟手工寫兩個版本的程式碼一樣快, 為了彌補呼叫時候 max<0>(v) 其意含不直覺的缺點, 可以使用 C++11 const_expr int X = 0; 或是其他你喜歡的手法避開這個問題。 希望對你的問題有幫助。 -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.185.67.169 ※ 編輯: yoco315 來自: 111.185.67.169 (06/29 01:46)
yoco315:full source code http://ideone.com/qLKXX 06/29 01:56
EdisonX:workship !! 06/29 02:27
purincess:^ worship ? XD 06/29 02:35
EdisonX:orz , worship is right. 06/29 02:53
purincess:actually i thought of "workshop" at first glance... 06/29 03:23
shininglion:worship!!!!! 06/29 08:35
shininglion:看來看去還是比較喜歡 specialized 的做法XD 06/29 08:48
azureblaze:可是pointer-to-member好像比較好閱讀 06/29 10:39
ericinttu:workshop 06/29 11:14
Chikei:http://ideone.com/HAuSk 供比較喜歡特化但沒有C++11又覺得 06/29 12:44
Chikei:數字不好閱讀的人參考 06/29 12:44
VictorTom:worship~~ 06/30 01:30