コンテンツにスキップ

C++/三方比較演算子

出典: フリー教科書『ウィキブックス(Wikibooks)』
< C++

C++20で導入された三方比較演算子(<=>)は、「宇宙船演算子」(spaceship operator)の愛称でも知られています。この演算子は、2つの値の関係(less、equal、greater)を単一の操作で判定できる総称的な比較を実現します。

基本概念

[編集]

三方比較演算子は、比較結果として以下のいずれかの型を返します:

  • std::strong_ordering
  • std::weak_ordering
  • std::partial_ordering
基本的な使用例:
#include <compare>
#include <iostream>

auto main() -> int {
    auto a{0.0}, b{a / a};
    
    auto result = a <=> b;

    if (result < 0)
        std::cout << "a は b より小さい\n";
    else if (result > 0)
        std::cout << "a は b より大きい\n";
    else if (result == 0) 
        std::cout << "a は b と等しい\n";
    else
        std::cout << "NaN?\n";
}

比較カテゴリ

[編集]

strong_ordering

[編集]

完全な順序関係を表現します。整数型などの厳密な比較が可能な型で使用されます。

  • less
  • equal
  • greater

weak_ordering

[編集]

大小関係は存在するが、同値性を持つ要素が存在する場合に使用されます。 例:大文字小文字を区別しない文字列比較

partial_ordering

[編集]

一部の値間で比較が定義されない可能性がある場合に使用されます。

浮動小数点数(NaNを含む場合)

クラスでの使用

[編集]

デフォルト実装

[編集]
struct Point {
    int x, y;
    auto operator<=>(const Point&) const = default;  // 自動生成
};

カスタム実装

[編集]
struct Point {
    int x, y;
    std::strong_ordering operator<=>(const Point& other) const {
        if (auto cmp = x <=> other.x; cmp != 0)
            return cmp;
        return y <=> other.y;
    }
};

特殊なケース

[編集]

NaNの処理

[編集]

浮動小数点数の比較では、NaN(Not a Number)の存在に注意が必要です:

#include <compare>
#include <cmath>

double nan = std::nan("1");
double num = 1.0;

auto result = nan <=> num;  // std::partial_ordering::unordered を返す

メリット

[編集]
  • 比較演算子の一貫した実装
  • ボイラープレートコードの削減
  • 型安全な比較操作
  • 標準ライブラリとの互換性

ベストプラクティス

[編集]
  • 可能な限り = default を使用する
  • 適切な比較カテゴリを選択する
  • NaNを含む可能性がある場合は partial_ordering を使用する
  • 比較の推移性を保証する

三方比較演算子は、C++20以降のモダンなコードにおいて、オブジェクトの比較を簡潔かつ効率的に実装するための重要な機能です。特に、クラス型の比較操作を実装する際に、コードの可読性と保守性を大きく向上させることができます。