5

什麼是最好的(如果有的話)?Barton-Nackman vs std :: enable_if

變A(巴頓Nackman):

template<class T> 
struct equal_comparable { 
    friend bool operator == (const T & t1, const T & t2) { 
     return t1.equalTo (t2); 
    } 
}; 

class MyClass : private equal_comparable<MyClass> { 
    bool equalTo (const MyClass & other) //... 
}; 

變B(STD :: enable_if):

struct MyClass { 
    static const bool use_my_equal = true; 
    bool equalTo (const MyClass & other) //... 
}; 

template<class T> 
typename std::enable_if< 
    T::use_my_equal, 
    bool 
>::type 
operator == (const T & t1, const T & t2) { return t1.equalTo (t2); } 
+0

我個人比較喜歡前者。 'equal_comparable'可以放在一個合適的名字空間中,但是誰知道''use_my_equal'成員被某種'T'使用,你從來沒有聽說過。當然,這個問題也適用於'enable_if'的其他類似用途 - 僅僅因爲依賴名稱解析並不一定*意味着名稱被用於你認爲它的意思,如果你將它從命名空間中拉出來不要控制。您可以改用類型特徵。 –

+0

爲什麼要使用模板?爲什麼不只是'bool operator ==(const MyClass&,/ * etc * /);?' – GManNickG

+0

@GManNickG:我相信這個技巧的目的是減少每個類的平等可比性所需的樣板。 –

回答

4

我寧願使用由@SteveJessop在評論中提到Boost.Operators,從而使您的第一種方法正式化並自動化。如果您碰巧需要多組操作符(因此需要多重繼承),它們還會處理空基優化。這不僅僅是節省了打字費用,還有代碼文檔/執行價值,因爲這些基類正好在類接口的前端。從這個意義上說,這是一種原始的概念。