奇怪的重复模板模式
在这种情况下,您提供一个简单的基类,它实现所有需要的运算符并简单地继承它:
template <class T>
struct implement_relational_operators{
friend bool operator<=(const T & a,const T & b){ return a < b || a == b; }
friend bool operator>(const T & a, const T & b){ return !(a <= b); }
friend bool operator!=(const T & a, const T & b){ return !(a == b);}
friend bool operator>=(const T & a, const T & b){ return !(a < b); }
};
template <class T>
struct scalar : public implement_relational_operators<scalar<T> >{
T value;
bool operator<(const scalar& o) const { return value < o.value;}
bool operator==(const scalar& o) const { return value == o.value;}
};
这不具有以下缺点std::rel_ops
(见下文)。但是,您仍然需要实施operator<
and operator==
。使用了类似的技巧boost http://www.boost.org/doc/libs/1_57_0/boost/operators.hpp.
C++20's <=>
可能会进一步改善情况(见下文)。
std::rel_ops
(在 C++20 中已弃用)
std::rel_ops
提供基于的附加操作<
an ==
,所以你只需要编写两个运算符。
但是,它在 C++20 中将被弃用,其中a <=> b http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0768r1.pdf将被卷入其中。
要求
你只需要平等(operator=
) 和小于 (operator<
) 比较运算符。其余的可以自动生成std::rel_ops http://en.cppreference.com/w/cpp/utility/rel_ops/operator_cmp,因为以下成立:
a != b equal to !(a == b)
a <= b equal to (a < b) || (a == b)
a >= b equal to !(a < b)
a > b equal to !(a <= b)
请注意,这些的效率低于手写的效率。
Warning
但是,由于您自己提供这些运算符很容易,因此您应该付出额外的努力来编写它们。正如所提到的,它们也有一些缺点R·马蒂尼奥·费尔南德斯 https://stackoverflow.com/questions/13917848/how-to-best-overload-operator-but-only-write-one-or-two-comparison-fun#comment19184363_13917897:
请注意,[它们]将无法正常工作,除非您:
- add
using namespace std::rel_ops
在您使用运算符的每个上下文中;或者
- add
using::operator!=; using::operator<=; using::operator>=; using::operator>;
在你的类的命名空间中(using namespace std::rel_ops
在类的命名空间中是不可接受的,因为它不会被 ADL 拾取)。