2

如果我们想基于一个已经拥有这些运算符的成员来制作一个类的所有关系运算符,那么没有比这更短的方法了吗?

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; }
4

3 回答 3

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定义,而不是根据member定义,即

bool operator !=(const foo &lhs, const foo &rhs) { return !(lhs == rhs); }
于 2013-06-09T10:11:01.233 回答
2

这很短,但是您可以通过 compareTo() 方法来定义它们,该方法返回负数、零或正数,根据 ab 是负数、零或正数:

  • ==: compareTo() 返回零
  • !=: compareTo() 返回非零
  • <: compareTo() 返回负数
  • >=: compareTo() 返回 >= 0。
  • >: compareTo() 返回正数
  • <=: compareTo() 返回 <= 0

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

于 2013-06-09T10:02:52.983 回答
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!)。

于 2013-06-09T11:44:19.353 回答