|
| 1 | +# type_order |
| 2 | +* compare[meta header] |
| 3 | +* std[meta namespace] |
| 4 | +* class template[meta id-type] |
| 5 | +* cpp26[meta cpp] |
| 6 | + |
| 7 | +```cpp |
| 8 | +namespace std { |
| 9 | + template <class T, class U> |
| 10 | + struct type_order { |
| 11 | + static constexpr strong_ordering value = TYPE-ORDER(T, U); // 説明専用 |
| 12 | + |
| 13 | + using value_type = strong_ordering; |
| 14 | + |
| 15 | + constexpr operator value_type() const noexcept { return value; } |
| 16 | + constexpr value_type operator()() const noexcept { return value; } |
| 17 | + }; |
| 18 | + |
| 19 | + template <class T, class U> |
| 20 | + constexpr strong_ordering type_order_v = type_order<T, U>::value; |
| 21 | +} |
| 22 | +``` |
| 23 | +* strong_ordering[link strong_ordering.md] |
| 24 | + |
| 25 | +## 概要 |
| 26 | +2つの型`T`と`U`の間の、コンパイル時の全順序を取得する。 |
| 27 | + |
| 28 | +これを使用することにより、型リストの正規化(例えば`typeset<A, B>`と`typeset<B, A>`を同じ型として扱う)や、複数の翻訳単位にわたって型の順序を一貫させることができる。 |
| 29 | + |
| 30 | + |
| 31 | +## 効果 |
| 32 | +`TYPE-ORDER(T, U)`は実装定義であり、すべての型に対する全順序を表す。以下の保証がある: |
| 33 | + |
| 34 | +- 反射律: `type_order_v<T, T>`は[`strong_ordering::equal`](strong_ordering.md) |
| 35 | +- 反対称律: `type_order_v<T, U>`が`less`であれば、`type_order_v<U, T>`は`greater` |
| 36 | +- 推移律: 通常の推移性 |
| 37 | +- CV修飾や参照修飾の異なる型は別個の型として区別される(例: `int`、`const int`、`int&`は順序として`equal`ではない) |
| 38 | + |
| 39 | +実装は、型の同名異シグニチャ化に使用される既存のABIマングリング基盤を利用することが想定される。実装は推奨事項として、テンプレートの第i引数のみが異なる場合に、`X<...,T,...>`と`X<...,U,...>`の順序が`T`と`U`の順序と一致するように再帰的な一貫性を提供することができる。 |
| 40 | + |
| 41 | + |
| 42 | +## 備考 |
| 43 | +- C++26より前は、型の全順序を得るためには`__PRETTY_FUNCTION__`等の処理系固有の機能を使うか、`typeid`を実行時に比較する必要があった。`type_order`は、コンパイル時に取得できる、実装定義であるが安定した型の全順序を提供する |
| 44 | +- このクラスは不完全型に対しても動作する |
| 45 | +- 実装定義の全順序の具体的な順番には依存すべきではないが、同じ実装のなかでは翻訳単位の境界をまたいでも安定する |
| 46 | + |
| 47 | + |
| 48 | +## 例 |
| 49 | +```cpp example |
| 50 | +#include <compare> |
| 51 | +#include <type_traits> |
| 52 | + |
| 53 | +struct A {}; |
| 54 | +struct B {}; |
| 55 | + |
| 56 | +int main() { |
| 57 | + // 同じ型同士の比較はequal |
| 58 | + static_assert(std::type_order_v<int, int> == std::strong_ordering::equal); |
| 59 | + |
| 60 | + // 異なる型同士の順序は実装定義だが、反対称性は保証される |
| 61 | + constexpr auto ord_ab = std::type_order_v<A, B>; |
| 62 | + constexpr auto ord_ba = std::type_order_v<B, A>; |
| 63 | + static_assert(ord_ab != std::strong_ordering::equal); |
| 64 | + static_assert((ord_ab < 0) == (ord_ba > 0)); |
| 65 | + static_assert((ord_ab > 0) == (ord_ba < 0)); |
| 66 | + |
| 67 | + // CV修飾の違いも区別される |
| 68 | + static_assert(std::type_order_v<int, const int> != std::strong_ordering::equal); |
| 69 | +} |
| 70 | +``` |
| 71 | +
|
| 72 | +### 出力 |
| 73 | +``` |
| 74 | +``` |
| 75 | +
|
| 76 | +
|
| 77 | +## バージョン |
| 78 | +### 言語 |
| 79 | +- C++26 |
| 80 | +
|
| 81 | +### 処理系 |
| 82 | +- [Clang](/implementation.md#clang): 22 [mark noimpl] |
| 83 | +- [GCC](/implementation.md#gcc): 16 [mark verified] |
| 84 | +- [Visual C++](/implementation.md#visual_cpp): 2026 Update 2 [mark noimpl] |
| 85 | +
|
| 86 | +
|
| 87 | +## 関連項目 |
| 88 | +- [`strong_ordering`](strong_ordering.md) |
| 89 | +- [`std::meta::type_order`](/reference/meta/type_order.md) |
| 90 | +
|
| 91 | +
|
| 92 | +## 参照 |
| 93 | +- [P2830R10 Constexpr Type Ordering](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html) |
| 94 | +- [P3778R0 Fix for `type_order` template definition](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3778r0.html) |
0 commit comments