我是否必须手动为比较运算符实现可交换性?

iFr*_*cht 7 c++ comparison operator-overloading c++11

n个不同的类,它们都应该与之相当,operator==并且operator!=有必要手动实现(n ^ 2 - n)*2个运算符.(至少我认为这是一个术语)

三个班级将是12个,四个班级为24个.我知道我可以用其他运算符来实现很多这样的运算符:

operator==(A,B); //implemented elsewhere

operator==(B,A){ return A == B; }

operator!=(A,B){ return !(A == B); }
Run Code Online (Sandbox Code Playgroud)

但它似乎仍然很乏味,特别是因为它A == B总会产生相同的结果,B == A并且似乎没有任何理由来实现它们的两个版本.

有没有解决的办法?难道我真的要落实A == BB == A手动?

Pra*_*ian 9

使用Boost.Operators,然后你只需要实现一个,boost将为你定义其余的样板.

struct A
{};

struct B : private boost::equality_comparable<B, A>
{
};

bool operator==(B const&, A const&) {return true;}
Run Code Online (Sandbox Code Playgroud)

这允许以任何顺序比较等式/不等式的实例AB进行比较.

现场演示

注意: private由于Barton-Nackman技巧,继承在这里起作用.

  • @iFreilicht不,很可能不是.这只是一个示例实现:).真正的实现可能会比较"A"和"B"的数据成员来确定相等性. (2认同)
  • 当你把操作数混为一谈时,你要小心这一点!如果你使用带有`<T,U>`的双参数形式,你应该从`T`派生,而不是从'U`派生.请参阅Boost.Operators的[文档](http://www.boost.org/doc/libs/1_55_0/libs/utility/operators.htm#two_arg).对于比较运算符,这实际上是允许的,但是其他读者可能没有意识到它,因此恕我直言在这里更好. (2认同)
  • @iFreilicht是的,[确实](http://coliru.stacked-crooked.com/a/793a9cea89720cb5). (2认同)
  • @iFreilicht虽然Praetorian所说的是正确的,但还有一点需要注意:如果您碰巧在Windows上编写代码,请考虑使用[base-class chaining](http://www.boost.org/doc/libs/1_53_0 /libs/utility/operators.htm#chaining)保持类的大小很小,即使用`struct C:private boost :: equality_comparable <C,A,boost :: equality_comparable <C,B >> {}; `.丑陋的语法,但遗憾的是由于Windows上的ABI搞砸了.如果你在Linux上,...你可以放心地忽略这个:) (2认同)