看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《minazukimaya (水無月真夜)》之銘言: : : ◆ From: 114.32.15.163 : : → minazukimaya:好處是function call成本比較低啊 當然缺點就是靈活 10/05 16:50 : : → minazukimaya:度比較差 10/05 16:50 : : → adrianshum:最大問題是把本來的class 污染了, 用 external functor 10/05 16:52 : : → adrianshum:其中一個原因就是想改 sorting criteria 的時候不需改 10/05 16:52 : : → adrianshum:model, 但這做法, 每加一個就要改一次 model 10/05 16:53 : 加上getXXX()的做法也是每加一次要改一次model啊.. : 同樣都是汙染原本的class : 為什麼你為認為加十個getter比加一個template function汙染得少呢? : 要提取class其中的private成員 本來就勢必要在class裡面加東西 : 兩者的差別只在你加的是member function還是template member function而已 我本來的意思就是說, 你的做法是在加一堆 getXxx 呀. :) 我覺得比較好的做法, 就是根據 sorting criteria 不同 來寫不同的 functor. 本身 model 有提供方法去 access 內部資料的話, 這樣根本不必動到 model 本身. : : → 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> ();} : } : 寫十個前者到底哪裡比較好.. 1) non-intrusive 2) 你本來的寫法, 只能以一個 field 來 sort 3) 容易理解 : 除了增加code的長度和降低維護性之外.. 增加的長度和你本來的 code 相比其實不多. 而維護性, 我個人覺得和你原本的相比沒有那裡有比 較低, 反而因為容易理解而更好維護. 有時候可維護 性和 code 長度未必成反比. 比如你的做法, sorting 的時候要 base on multiple field 的話 (相信我, 這非常常見, 非常 real-world), 就沒輒了, 除非弄一個 temp value object 再 override 其 < operator 才行. 但這種做法真的是好維護易明瞭嗎? : 寫十個functor然後每個functor只差9個字元 這樣真的比較好嗎 試用五個 field 的情況加上最簡單的使用 (沒有 我上面說的多field sorting) 比較一下, 是不是重覆得少? (我不太記得你的 code 了, 做個大概): 本來的 class: class Foo { private: int f1; int f2; int f3; int f4; int f5; public: // accessing methods } 你的方法: enum SortByAttr{ ATTR1, ATTR2, ATTR3, ATTR4, ATTR5 } class Foo { private: int f1; int f2; int f3; int f4; int f5; public: // accessing methods template<SortByAttr T> void getAttr() {}; template<> int getAttr<ATTR1>() { return f1; }; template<> int getAttr<ATTR2>() { return f2; }; template<> int getAttr<ATTR3>() { return f3; }; template<> int getAttr<ATTR4>() { return f4; }; template<> int getAttr<ATTR5>() { return f5; }; } template <Foo::SortByAttr T> class LessThanBy { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getAttr<T>() < rhs.getAttr<T>; } 我的寫法: (class Foo 沒變) class LessThanByF1 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF1() < rhs.getF1(); } class LessThanByF2 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF2() < rhs.getF2(); } class LessThanByF3 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF3() < rhs.getF3(); } class LessThanByF4 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF4() < rhs.getF4(); } class LessThanByF5 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF5() < rhs.getF5(); } 除了那幾句基本 language constructs (class LessThanByFx, public:, oeprator().... ) logic 上根本沒有多少重覆的地方. code 也不見得比你的 做法長多少, 更何況你的做法也不是沒有重覆. 要加一個新的 sorting field, 你的做法要: 1) enum 加一個新 entry 2) 加一個template method 我的做法 (正常 field 會有 accessor 了) 只要加 一個 functor. 真的會比較難維護? 還有你裡面假定 1) 只用一個 attrib 做 sort 2) attrib 有適當的 < operator 反而令東西更難維護了. 像我上面所說, 假設想 sort by name, 所謂 sort by name 是先以 last name 再以 first name. 而 name 在 Foo 內是以 char* 存放 (非常正常合理的例子吧), 我只要在 functor 內寫好比較的方法就行吶, 可是你的做法呢? 或者 code 長度看來也還是會差不多, 但維護起來就差很遠了. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 202.155.236.82 ※ 編輯: adrianshum 來自: 202.155.236.82 (10/05 18:00)
minazukimaya:你把兩件事混在一起講了 10/05 18:04
minazukimaya:getter function是不是template 和 10/05 18:05
minazukimaya:comparator functor是不是template是兩回事 10/05 18:05
minazukimaya:另外原本的class是沒有getter的 不管你用哪種方法 10/05 18:06
minazukimaya:加getter進去都是汙染.. 10/05 18:06
adrianshum:作為 value object, 本身就有 getter 是很正常的, 可 10/05 18:07
adrianshum:是你的做法, 除了本身 model 正常的 getter, 還要另外 10/05 18:07
adrianshum:加這個為了 sorting 而生的 "另一堆 getter", 這就是 10/05 18:08
adrianshum:我所謂 intrusive 的原因 10/05 18:08
minazukimaya:如果你說要額外加新的criteria,而這個criteria具有 10/05 18:09
minazukimaya:某種獨特性,那它就只會有一個 所以額外寫一個當然 10/05 18:10
minazukimaya:是不用template template幫你把十個functor壓縮成 10/05 18:10
minazukimaya:一個 但是沒說你所有的criteria都要寫進這個 10/05 18:10
minazukimaya:template裡 10/05 18:10
LPH66:也並沒有都要啊:P template 不是寫了什麼才生什麼嗎... 10/05 18:14
adrianshum:問題就在於統一性了, 類似的情況要用不同的方法解決, 10/05 18:15
adrianshum:維護起來當然變得困難 :) 我不否認你的做法是變有趣 10/05 18:17
adrianshum:而在某些應用上是變實用的,只是用在這地方不太適合而已 10/05 18:17
minazukimaya:你現在在說的是哪個?getter function是template 10/05 18:22
minazukimaya:還是compare functor是template? 10/05 18:22
minazukimaya:前者的話討論在上一篇的推文 後者的話我完全不能同 10/05 18:22
minazukimaya:意用十個functor取代一個template functor是好做法 10/05 18:22