最終更新日時(UTC):
が更新

履歴 編集

class template
<compare>

std::type_order(C++26)

namespace std {
  template <class T, class U>
  struct type_order {
    static constexpr strong_ordering value = TYPE-ORDER(T, U); // 説明専用

    using value_type = strong_ordering;

    constexpr operator value_type() const noexcept { return value; }
    constexpr value_type operator()() const noexcept { return value; }
  };

  template <class T, class U>
  constexpr strong_ordering type_order_v = type_order<T, U>::value;
}

概要

2つの型TUの間の、コンパイル時の全順序を取得する。

これを使用することにより、型リストの正規化(例えばtypeset<A, B>typeset<B, A>を同じ型として扱う)や、複数の翻訳単位にわたって型の順序を一貫させることができる。

効果

TYPE-ORDER(T, U)実装定義であり、すべての型に対する全順序を表す。以下の保証がある:

  • 反射律: type_order_v<T, T>strong_ordering::equal
  • 反対称律: type_order_v<T, U>lessであれば、type_order_v<U, T>greater
  • 推移律: 通常の推移性
  • CV修飾や参照修飾の異なる型は別個の型として区別される(例: intconst intint&は順序としてequalではない)

実装は、型の同名異シグニチャ化に使用される既存のABIマングリング基盤を利用することが想定される。実装は推奨事項として、テンプレートの第i引数のみが異なる場合に、X<...,T,...>X<...,U,...>の順序がTUの順序と一致するように再帰的な一貫性を提供することができる。

備考

  • C++26より前は、型の全順序を得るためには__PRETTY_FUNCTION__等の処理系固有の機能を使うか、typeidを実行時に比較する必要があった。type_orderは、コンパイル時に取得できる、実装定義であるが安定した型の全順序を提供する
  • このクラスは不完全型に対しても動作する
  • 実装定義の全順序の具体的な順番には依存すべきではないが、同じ実装のなかでは翻訳単位の境界をまたいでも安定する

#include <compare>
#include <type_traits>

struct A {};
struct B {};

int main() {
  // 同じ型同士の比較はequal
  static_assert(std::type_order_v<int, int> == std::strong_ordering::equal);

  // 異なる型同士の順序は実装定義だが、反対称性は保証される
  constexpr auto ord_ab = std::type_order_v<A, B>;
  constexpr auto ord_ba = std::type_order_v<B, A>;
  static_assert(ord_ab != std::strong_ordering::equal);
  static_assert((ord_ab < 0) == (ord_ba > 0));
  static_assert((ord_ab > 0) == (ord_ba < 0));

  // CV修飾の違いも区別される
  static_assert(std::type_order_v<int, const int> != std::strong_ordering::equal);
}

出力

バージョン

言語

  • C++26

処理系

関連項目

参照