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,从而使您的第一种方法正式化并自动化。如果您碰巧需要多组操作符(因此需要多重继承),它们还会处理空基优化。这不仅仅是节省了打字费用,还有代码文档/执行价值,因为这些基类正好在类接口的前端。从这个意义上说,这是一种原始的概念。