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

ただし、他の演算子は ber ではなく foo で定義されることに注意てくださいmem

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

これはかなり短いですが、ab が負、ゼロ、または正であることに従って、負、ゼロ、または正を返す compareTo() メソッドの観点からそれらすべてを定義できます。

  • ==: 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 を使用できるクラスが少なくとも 2 つある場合に行うことですが、1 つのクラスについては気にしません。しかし、一般的な設計についても 2 度考えます。そのようなばかげたフォワードを強制されるとしたら、少し複雑すぎる可能性があります (KISS!)。

于 2013-06-09T11:44:19.353 に答える