更短的代码来定义所有关系运算符

时间:2013-06-09 09:48:35

标签: c++

如果我们想要基于已经拥有这些运算符的成员来创建类的所有关系运算符,那么没有比此更短的方法吗?

struct foo {
  some_class mem; //some_class already has all the relational operators
  //other members
}

//is there really no shorter way than to type these 6 functions?
bool operator==(const foo &lhs, const foo &rhs) { return lhs.mem == rhs.mem; }
bool operator!=(const foo &lhs, const foo &rhs) { return lhs.mem != rhs.mem; }
bool operator<(const foo &lhs, const foo &rhs) { return lhs.mem < rhs.mem; }
bool operator>(const foo &lhs, const foo &rhs) { return lhs.mem > rhs.mem; }
bool operator<=(const foo &lhs, const foo &rhs) { return lhs.mem <= rhs.mem; }
bool operator>=(const foo &lhs, const foo &rhs) { return lhs.mem >= rhs.mem; }

3 个答案:

答案 0 :(得分:5)

严格(使用所有功能的底层成员),否。

但是,您可以使用boost::operators来减少要实现的函数数量:

struct foo: boost::less_than_comparable<foo>, boost::equality_comparable<foo>
{
   some_class mem; //some_class already has all the relational operators
  //other members
}

bool operator<(const foo &lhs, const foo &rhs) { return lhs.mem < rhs.mem; }
bool operator==(const foo &lhs, const foo &rhs) { return lhs.mem == rhs.mem; }

但请注意,其他运算符将根据foo 定义,而不是mem ber 中的,即

bool operator !=(const foo &lhs, const foo &rhs) { return !(lhs == rhs); }

答案 1 :(得分:2)

这很短,但是您可以根据一个返回负数,零或正数的compareTo()方法来定义它们,根据a-b是负数,零或正数:

  • ==:compareTo()返回零
  • !=:compareTo()返回非零
  • &lt;:compareTo()返回否定
  • &gt; =:compareTo()返回&gt; = 0。
  • &gt;:compareTo()返回正数
  • &lt; =:compareTo()返回&lt; = 0

另请注意,上面的每个偶数行都是前一行的否定。

答案 2 :(得分:1)

除非您出于宗教原因试图保持清洁预处理器的使用,否则您的代码可以这样编写:

#define CALL_THROUGH_OPERATOR(operator_token, type_token, member_token) \
  operator##operator_token(const type_token& a, const type_token& b) { \
    return a.member_token operator_token b.member_token; \
  }

#define CALL_THROUGH_COMPARISONS(type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(< , type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(> , type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(!=, type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(<=, type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(>=, type_token, member_token) \
  bool CALL_THROUGH_OPERATOR(==, type_token, member_token)

CALL_THROUGH_COMPARISONS(foo, mem)

如果我有至少两个可以使用CALL_THROUGH_COMPARISONS的类,对于一个类,我会这样做,我不会打扰。但我也会考虑一般设计:如果它迫使我做这样愚蠢的前锋,那么它很可能有点过于复杂(KISS!)。