看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《minazukimaya (水無月真夜)》之銘言: : 加上getXXX()的做法也是每加一次要改一次model啊.. : 同樣都是汙染原本的class : 為什麼你為認為加十個getter比加一個template function汙染得少呢? : 要提取class其中的private成員 本來就勢必要在class裡面加東西 : 兩者的差別只在你加的是member function還是template member function而已 : : → adrianshum:根本和寫十個 compare_by_Xxx() compare_by_Yyy() 無異 10/05 16:53 : class LessThanByXXX { : public: : bool operator() (GNF& lhs,GNF& rhs) { return lhs.getXXX()<rhs.getXXX();} : }; : 這樣寫十個 和 : template <GNF::SortBy T> : class LessThanBy { : public: : bool operator() (GNF& lhs,GNF& rhs) { return lhs.getAttr<T>() < rhs.getAttr<T> ();} : } : 寫十個前者到底哪裡比較好.. : 除了增加code的長度和降低維護性之外.. : 寫十個functor然後每個functor只差9個字元 這樣真的比較好嗎 但是你沒有必要用enum做這件事 template<typename T, T (GNF::*getter)() const> class LessThanBy { public: bool operator() (const GNF& a, const GNF& b) { return (a.*getter)() < (b.*getter)(); } }; 這樣就好了 enum根本是多此一舉 -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.133.186.66
minazukimaya:template function call 和function pointer call 10/05 17:36
minazukimaya:效率不一樣 10/05 17:36
minazukimaya:當然compiler optimization也許可以解決這個問題 10/05 17:36
minazukimaya:但是這兩者不過是「效率」和「彈性」的trade-off 10/05 17:37
Fenikso:如果要在意幾個cycle的效率差那隨便你... 10/05 17:37
minazukimaya:可是這個comparator是用來sort的耶= = 10/05 17:38
minazukimaya:用來sort表示它會不斷的被call,也就是它的效率 10/05 17:38
minazukimaya:絕對影響整個sort的效率 而且是正比.. 10/05 17:38
minazukimaya:而且重點是 std和boost都有函式配接器幫你做這件事 10/05 17:39
minazukimaya:所以如果是要寫這種functor,根本不用親自動手 10/05 17:39
LPH66:效率上我不認為在 getter 都 inline 的情況下會是個問題 10/05 17:43
minazukimaya:透過pointer的函式呼叫本來就比較慢 這也是為什麼 10/05 17:43
minazukimaya:C的qsort會比std::sort慢的主要原因啊 10/05 17:43
LPH66:(getter 不 inline...你這 getter 還要做什麼事情啊 XD) 10/05 17:43
minazukimaya:當然如果優秀的compiler是有可能把pointer call 10/05 17:44
minazukimaya:轉成一般呼叫的 10/05 17:44
LPH66:std::sort 的 functor 的 operator () 呼叫和這裡的其實沒差 10/05 17:44
LPH66:多少的說... 10/05 17:44
minazukimaya:重點是你有沒有對某個函式進行取址的動作 10/05 17:45
LPH66:可是進 functor 之後位址是固定的... 10/05 17:45
minazukimaya:如果你要取址 inline就失效了 inline本身只是給 10/05 17:45
LPH66:不管是 functor 的 operator () 還是這裡的 fp 10/05 17:45
minazukimaya:compiler的「建議」 10/05 17:45
minazukimaya:compiler不一定真的幫你inline,特別是你會用到他的 10/05 17:46
minazukimaya:位址的時侯.. 10/05 17:46
LPH66:functor 的 operator () 對 compiler 來說還是一樣要取址啊 10/05 17:47
minazukimaya:不用 甚至有可能連函式呼叫都不用 10/05 17:47
LPH66:唔...所以即使這兩個位址都是 compile-time 已知仍然會有差? 10/05 17:50
minazukimaya:Inside the C++ Objective model有提到這個 10/05 17:51
LPH66:(我是指 functor 的 operator () 和這裡的 fp 位址) 10/05 17:51
minazukimaya:functor的operator()有可能用inline做掉啊 因為 10/05 17:52
minazukimaya:又沒有實際對它取址@@ 10/05 17:52
LPH66:那同樣是已知 function 為何 template 的寫法不會知道所呼叫 10/05 17:53
LPH66:的函式為何? 10/05 17:53
adrianshum:我覺得 F 大的做法更合理. 那丁點的 performance loss 10/05 17:53
LPH66:(我的觀念裡 template specialize 後那些tmpl. arg是固定的) 10/05 17:53
adrianshum:相比起維護性來說簡直不值一哂, code 看起來也更清楚 10/05 17:54
minazukimaya:你下面那篇才說用template寫functor不合理耶 10/05 17:59
minazukimaya:Fenikso和我的code差別只在於getter function要不要 10/05 18:00
minazukimaya:寫成template而已 10/05 18:00
minazukimaya:TO:LPH66 對 但是你一旦對某個getter function取址 10/05 18:01
minazukimaya:compiler勢必要生個位址出來 這樣它就不能inline了 10/05 18:01
minazukimaya:所以boost::function才要做個wrapper包起來 10/05 18:01
minazukimaya:以確保你在這樣用的時侯不會造成效能上的衝擊 10/05 18:02
LPH66:所以就是 high-level 的函式資訊有沒有被帶過去的關係了... 10/05 18:08
LPH66:(雖然我覺得就算包一層好像還是差不多的狀況...) 10/05 18:11
minazukimaya:包一層的話 帶過去實際的資訊是Type 10/05 18:11
minazukimaya:所以呼叫這個Type裡面的operator()的時侯 其實並 10/05 18:12
minazukimaya:沒有像傳function pointer進去一樣要經過一個取址 10/05 18:12
minazukimaya:這樣的話operator()就很可能被inline處理掉 10/05 18:13
LPH66:也就是說像這個 getter 的狀況包一層都不一定會比較好就是了 10/05 18:15
minazukimaya:在getter被傳進去之前就包起來 10/05 18:18
minazukimaya:就可以避免對getter()取址 10/05 18:19
adrianshum:我下一面對你做法最大的問題也在於 intrusive. 但 F大 10/05 18:24
adrianshum:的做法就能夠避免, 寫起來的分別可不能同日而語哦... 10/05 18:25
minazukimaya:等等 原本的class是沒有getter的 為什你會一直假 10/05 18:25
minazukimaya:設他有呢? 10/05 18:25
minazukimaya:如果原本的class有getter,那用std的函式配接器 10/05 18:27
minazukimaya:就可以解決sorting的問題 不需要另外再寫個functor 10/05 18:27
minazukimaya:std的functino adaptor事實上就是個template functor 10/05 18:28
minazukimaya:如果你需要更強大的功能 也有boost::bind 10/05 18:31
minazukimaya:和boost::function可以用 10/05 18:31
minazukimaya:TO LPH66: 剛剛我把你的問題再想了一遍 的確 10/05 19:39
minazukimaya:在compile time時template參數的位址是已知 所以 10/05 19:40
minazukimaya:好的compiler應該要把語法的indirect call 轉成 10/05 19:40
minazukimaya:direct call 10/05 19:40
minazukimaya:但是進一步來說能不能轉變成inline call,要由整個 10/05 19:41
minazukimaya:程式中究竟有沒有地方確實在run-time需要知道該 10/05 19:42
minazukimaya:function的位址來決定(ex.在runtime把該function取 10/05 19:42
minazukimaya:址,assign給某個變數之類) 10/05 19:42
minazukimaya:我想應該前幾大的compiler都會有這種優化能力(大概 10/05 19:44