Re: [問題] 相似的功能但不知如何合併
我舉實際一點的例子,比方說取得 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)
→
06/29 01:56, , 1F
06/29 01:56, 1F
推
06/29 02:27, , 2F
06/29 02:27, 2F
→
06/29 02:35, , 3F
06/29 02:35, 3F
推
06/29 02:53, , 4F
06/29 02:53, 4F
→
06/29 03:23, , 5F
06/29 03:23, 5F
推
06/29 08:35, , 6F
06/29 08:35, 6F
推
06/29 08:48, , 7F
06/29 08:48, 7F
推
06/29 10:39, , 8F
06/29 10:39, 8F
推
06/29 11:14, , 9F
06/29 11:14, 9F
推
06/29 12:44, , 10F
06/29 12:44, 10F
→
06/29 12:44, , 11F
06/29 12:44, 11F
推
06/30 01:30, , 12F
06/30 01:30, 12F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):
1
31
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章