2010-12-14 60 views
7

我有MyClass列表:什麼情況更好?

struct MyClass { 
    bool is_old_result(int lifetime); 
}; 
std::list<MyClass> results; 
int lifetime = 50; // or something else 

什麼情況下刪除的是更好的(C++的設計和性能比較):

results.remove_if(
    std::bind2nd(std::mem_fun_ref(&MyClass::is_old_result), lifetime)); 

results.remove_if(boost::bind(&MyClass::is_old_result, _1, lifetime)); 

struct RemoveFunctor { 
    RemoveFunctor (int lifetime) : lifetime(lifetime) {} 
    bool operator()(const MyClass & m) { return m.is_old_result(lifetime); } 
private: 
    int lifetime; 
}; 
results.remove_if(RemoveFunctor(lifetime)); 

爲什麼?

P.S.請不要使用lambda函數,也不要使用C++ 0x。

回答

12

在設計方面,使用bind的那個絕對是最清晰的。 (接着是顯式函數對象)。爲什麼?簡潔。

在性能方面,函數對象應該是無與倫比的(一切都可以很容易地分析和內聯)。根據編譯器優化的方式,使用bind的編譯器可能會匹配它(根據編譯器的分析,對is_old_result的調用可能通過指針,也可能不通過指針)。

+0

我完全同意。 – ltjax 2010-12-14 14:45:36

+0

我同意,綁定語法是最容易閱讀的。如果表現是次要問題,請在這裏進行綁定。 – 2010-12-14 14:46:47

+3

我同意,並且我會補充說,除非您已經分析並確定此聲明是性能瓶頸,否則性能應該是次要問題。 – 2010-12-14 15:03:27

3

隨着更合適的命名,如「IsOldResult」或「ResultOlderThan」,我會說,最終的解決方案將是最可讀的,因爲這是最通行證散文所述一個:

results.remove_if(ResultOlderThan(lifetime)); 

但是,如果它所表示的算法出現在多個上下文中,我可能只會去編寫仿函數。寫一個從單個單線呼叫站點中刪除的5線課程似乎對我來說過於浪費。

否則,boost :: bind選項有我的投票,因爲它和std :: bind2nd(分別是_1和std :: mem_fun_ref)之間的最小附加fluff。另外,boost :: bind一般適用於更多的情況,比如你不僅僅綁定只有兩個參數的函數的一個變量。

+0

關於合適的'ResultOlderThan' – 2010-12-14 21:09:46

相關問題