LoginSignup
2
2

More than 5 years have passed since last update.

operator<だけで、比較演算子も等値演算子も

Last updated at Posted at 2018-05-26

はじめに

std::rel_opsboost::operatorsを使うことで、演算子の実装の手間を省くことができます。実装の手間を省くことができるというのはDRY原則からしても、とても素晴らしいことです。
通常、これらを利用する場合operator <operator==を実装してくれれば、残ってる奴らは全部やっとくよ!というものですが、実はoperator <だけで、すべて済みますという話です。

mix-inの実装

boost::operatorsと同じですが、まず比較演算子の実装です。

template <typename T>
class Operators {
public:
    friend bool operator >(const T& lhs, const T& rhs) { return rhs < lhs; }
    friend bool operator<=(const T& lhs, const T& rhs) { return !(lhs > rhs); }
    friend bool operator>=(const T& lhs, const T& rhs) { return !(lhs < rhs); }
};

このOperatorsを継承することで、operator <を実装しとけばoperator >operator<=operator>=も使えるようになるということです。

等値演算子も追加しちゃう

実はa < bb < aならa != bなので、これを利用することで等値演算子も追加できます。

template <typename T>
class Operators {
public:
    friend bool operator >(const T& lhs, const T& rhs) { return rhs < lhs; }
    friend bool operator<=(const T& lhs, const T& rhs) { return !(lhs > rhs); }
    friend bool operator>=(const T& lhs, const T& rhs) { return !(lhs < rhs); }

    friend bool operator!=(const T& lhs, const T& rhs) { return (lhs < rhs) || (rhs < lhs); }
    friend bool operator==(const T& lhs, const T& rhs) { return !(lhs != rhs); }
};

こいつ継承することで、operator <を実装しとけば、加えてoperator==operator!=も使えるようになります。

なんでboostとかに用意されてないわけ?

問題が仮にあったとして、選択肢としてこんな感じのmix-inクラスを持っておくのは、いいことだと思いますと前置きした上で、ちょっとした雑談を。

パフォーマンスから考える

operator==operator!=も、それなりにパフォーマンスが必要なケースが多く、関数を引きまわすとパフォーマンス上よくはありません。(実際にバイナリになったときに影響が出るかどうかは置いといて)
ですので、operator==はシンプルにフィールド比較するくらいが精神衛生上も良いかもしれません。

ユースケースから考える

演算子添加のユースケースとしては以下が考えられます。

  1. 等値演算子だけ実装して、比較演算子は実装しない
  2. 比較演算子だけ実装して、等値演算子は実装しない
  3. 比較演算子も実装して、等値演算子も実装する

個人的には、テストも書きたいので1は必要というケースがもっとも多い気がします。
そのあとstd::setの要素や、std::mapのキーにしたいときには、operator <を実装して、せっかくなのでboost::less_than_comparableをついでに継承することがありますね。これが3のケースですね。
2から3という状況は、うーん…たしかにあまりないかもしれませんね。結局、これがないのは、そこまで需要がないということなんでしょう。

まとめ

便利です。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2