名前空間
変種
操作

比較演算子

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
一般
値カテゴリ (lvalue, rvalue, xvalue)
評価順序 (副作用完了点)
定数式
未評価式
一次式
ラムダ式(C++11)
リテラル
整数リテラル
浮動小数点リテラル
ブーリアンリテラル
文字リテラル および エスケープシーケンス
文字列リテラル
ヌルポインタリテラル(C++11)
ユーザ定義リテラル(C++11)
演算子
代入演算子: a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
インクリメントとデクリメント: ++a, --a, a++, a--
算術演算子: +a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
論理演算子: a||b, a&&b, !a
比較演算子: a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
メンバアクセス演算子: a[b], *a, &a, a->b, a.b, a->*b, a.*b
その他の演算子: a(...), a,b, a?b:c
デフォルト比較(C++20)
演算子の代替表現
優先順位と結合性
畳み込み式(C++17)
new 式
delete 式
throw 式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
演算子オーバーロード
変換
暗黙の変換
const_cast
static_cast
reinterpret_cast
dynamic_cast
明示的な変換 (T)a, T(a)
ユーザ定義変換
 

引数を比較します。

演算子の名前 構文 オーバーロード可能 プロトタイプの例 (class T に対して)
メンバ関数として 自由関数として
等しい a == b Yes bool T::operator ==(const T2 &b) const; bool operator ==(const T &a, const T2 &b);
等しくない a != b Yes bool T::operator !=(const T2 &b) const; bool operator !=(const T &a, const T2 &b);
小さい a < b Yes bool T::operator <(const T2 &b) const; bool operator <(const T &a, const T2 &b);
大きい a > b Yes bool T::operator >(const T2 &b) const; bool operator >(const T &a, const T2 &b);
小さいまたは等しい a <= b Yes bool T::operator <=(const T2 &b) const; bool operator <=(const T &a, const T2 &b);
大きいまたは等しい a >= b Yes bool T::operator >=(const T2 &b) const; bool operator >=(const T &a, const T2 &b);
三方比較 (C++20) a <=> b Yes /*see description*/ T::operator <=>(const T2 &b) const; /*see description*/ operator <=>(const T &a, const T2 &b);
ノート
  • 組み込みの演算子が bool を返すところでは、ほとんどのユーザ定義のオーバーロードも、組み込みのものと同じ方法で使用できるようにするために、 bool を返します。 しかし、ユーザ定義の演算子オーバーロードでは、任意の型 (void も含む) を戻り値型として使用することができます。
  • T2 には T を含む任意の型を使用できます。

目次

[編集] 二方比較

二方比較演算子の式は以下の形式を持ちます。

lhs < rhs (1)
lhs > rhs (2)
lhs <= rhs (3)
lhs >= rhs (4)
lhs == rhs (5)
lhs != rhs (6)
1) lhsrhs より小さい場合は true、そうでなければ false を返します。
2) lhsrhs より大きい場合は true、そうでなければ false を返します。
3) lhsrhs より小さいまたは等しい場合は true、そうでなければ false を返します。
4) lhsrhs より大きいまたは等しい場合は true、そうでなければ false を返します。
5) lhsrhs と等しい場合は true、そうでなければ false を返します。
6) lhsrhs と等しくない場合は true、そうでなければ false を返します。

すべての場合において、組み込みの演算子に対しては、左辺値から右辺値配列からポインタおよび関数からポインタへの標準変換の後、 lhsrhs は以下のいずれかでなければなりません。

  • 算術型または列挙型 (後述の算術比較演算子を参照してください)
  • ポインタ型 (後述のポインタ比較演算子を参照してください)

上記の標準変換の前に両方の被演算子が配列型であった場合の比較は非推奨です。 (C++20およびそれ以降)

いずれの場合でも、結果は bool の純粋右辺値です。

[編集] 算術比較演算子

被演算子が算術型または列挙型 (スコープ付きまたはスコープなし) の場合、算術演算子のルールに従って両方の被演算子に対して通常の算術変換が行われます。 変換後、その値が比較されます。

[編集]

#include <iostream>
int main()
{
    std::cout << std::boolalpha;
    int n = -1;
 
    int n2 = 1;
    std::cout << " -1 == 1? " << (n == n2) << '\n'
              << "Comparing two signed values:\n"
              << " -1  < 1? " << (n < n2) << '\n'
              << " -1  > 1? " << (n > n2) << '\n';
 
    unsigned int u = 1;
    std::cout << "Comparing signed and unsigned:\n"
              << " -1  < 1? " << (n < u) << '\n'
              << " -1  > 1? " << (n > u) << '\n';
 
    unsigned char uc = 1;
    std::cout << "Comparing signed and smaller unsigned:\n"
              << " -1  < 1? " << (n < uc) << '\n'
              << " -1  > 1? " << (n > uc) << '\n';
}

出力:

 -1 == 1? false
Comparing two signed values:
 -1  < 1? true
 -1  > 1? false
Comparing signed and unsigned:
 -1  < 1? false
 -1  > 1? true
Comparing signed and smaller unsigned:
 -1  < 1? true
 -1  > 1? false

[編集] ポインタ比較演算子

比較演算子は、2つのポインタ (またはメンバポインタ (operator== および operator!= に対してのみ))、またはポインタとヌルポインタ定数、または2つのヌルポインタ定数 (ただし少なくとも片方が std::nullptr_t でなければなりません (ヌルとヌルの比較は算術比較のルールに従います)) (C++14以前)を比較するために使用することができます。

まず、合成ポインタ型を得るために、両方の被演算子にポインタ変換 (引数がメンバポインタの場合はメンバポインタ変換)、関数ポインタ変換 (C++17およびそれ以降)、および修飾変換が以下のように適用されます。

1) 両方の被演算子がヌルポインタ定数の場合、合成ポインタ型は std::nullptr_t です。
2) 片方の被演算子がヌルポインタ定数で、他方がポインタの場合、合成型は正確にそのポインタ型です。
3) 片方の被演算子が cv1 void へのポインタで、他方が cv2 T へのポインタの場合、合成型は cv12 void へのポインタです。 ただし T は何らかのオブジェクト型または void で、 cv12cv1cv2 の和です。
4) 両方の被演算子が同じ型への cv 修飾が異なるポインタの場合、合成型は引数の cv 修飾の和の cv 修飾を持つ、その同じ型へのポインタです。
(C++14以前)
4) 被演算子の型が T1 (または cv 修飾された T1) へのポインタ P1 と T2 (または cv 修飾された T2) へのポインタ P2 の場合、 T1 が T2 と同じであるか T2 の基底クラスであれば、合成ポインタ型は P1 と P2 の cv 結合された型です。 そうでなく、 T2 が T1 の基底クラスであれば、合成ポインタ型は P2 と P1 の cv 結合された型です。
5) 被演算子の型が U1 (または cv 修飾された U1) の T1 型メンバへのポインタ MP1 と U2 (または cv 修飾された U2) の T2 型メンバへのポインタ MP2 の場合、 T1 が T2 と同じであるかその派生であれば、合成ポインタ型 MP1 と MP2 の cv 結合された型です。 そうでなく、 T2 が T1 の派生であれば、合成ポインタ型は MP2 と MP1 の cv 結合された型です。
6) 被演算子 P1 と P2 の型が多段の混合ポインタと同じ段数のメンバポインタ型で、その任意の段における cv 修飾が異なるだけの場合、合成ポインタ型は P1 と P2 の cv 結合された型です。

上の定義において、2つのポインタ型 P1 と P2 の cv 結合された型とは、 P1 と同じ段数を持ち、そのすべての段において、 cv 修飾が以下のように設定されていることを除いて P1 と同じ型を持つ型です。

a) 最上段以外のすべての段において、その段の P1 と P2 の cv 修飾の和になります。
b) 任意の段における結果の cv 修飾が同じ段の P1 または P2 の cv 修飾と異なる場合、その段と最上段の間のすべての段に const が追加されます。

例えば、 void*const int* の合成ポインタ型は const void* で、 int**const int** の合成ポインタ型は const int* const*です。 C++14 までは int**const int** は比較できなかったことに注意してください。

(C++14およびそれ以降)

上記に加えて、関数ポインタ型と noexcept 関数ポインタ型の合成ポインタ型は (その関数型が同じであれば) 関数ポインタ型になります。

(C++17およびそれ以降)

これは、任意のポインタ型は void* と比較できるということを暗黙に意味します。

2つのオブジェクトへのポインタ (の変換後) の比較の結果は、以下のように定義されます。

1) 2つのポインタが同じ配列の異なる要素を指している場合、または同じ配列の異なる要素内の部分オブジェクトを指している場合、大きい添字を持つ要素を指しているポインタの方が他方より大きいとみなされます。 別の言い方をすると、ポインタの比較の結果は、それらが指している要素のインデックスを比較した結果と同じになります。
2) 片方のポインタが配列の要素を指すか配列の要素の部分オブジェクトを指し、他方のポインタがその配列の最後の要素の次の要素を指す場合、後者のポインタの方が前者より大きいとみなされます。 単一のオブジェクトを指しているポインタは、サイズ1の配列を指しているとみなされます。 つまり &obj+1&obj より大きいとみなされます。 (C++17およびそれ以降)
3) union でないクラス型のオブジェクト内で、2つのポインタが同じメンバアクセスを持つ異なる非静的データメンバを指している場合、またはそのようなメンバの部分オブジェクトまたは配列要素を指している場合、後に宣言されたメンバを指しているポインタの方が他方より大きいとみなされます。 別の言い方をすると、同じメンバアクセスモードを持つクラスメンバは、宣言された順番でメモリ内に配置されます。

2つのポインタ (の変換後) の等値比較の結果は、以下のように定義されます。

1) ポインタがどちらもヌルポインタの場合、それらは等しいとみなされます。
2) ポインタが関数ポインタで、同じ関数を指している場合、それらは等しいみなされます。
3) ポインタがオブジェクトポインタで、同じアドレスを表している場合、それらは等しいとみなされます (これには、同じ共用体の非静的メンバを指している2つのポインタや、標準レイアウト構造体を指しているポインタとその最初のメンバを指しているポインタや、 reinterpret_cast によって関連付けられているポインタなどが含まれます)。
4) それ以外のすべてのポインタは等しくないとみなされます。

メンバポインタ (の変換後) の比較の結果は、以下のように定義されます。

1) メンバポインタがどちらもヌルメンバポインタ値の場合、それらは等しいとみなされます。
2) そうでなく、2つのポインタのどちらかだけがヌルメンバポインタ値の場合、それらは等しくないとみなされます。
3) そうでなく、どちらかが仮想メンバ関数を指している場合、結果は未規定です。
4) そうでなく、2つのポインタが同じ最も派生したオブジェクトの同じメンバを参照する場合、または関連するクラス型の架空のオブジェクトで逆参照した場合に同じ部分オブジェクトを参照する場合、それらは等しいとみなされます。
5) そうでなければ、それらは等しくないとみなされます。

p<=qp>=q がどちらも true で、 p<qp>q がどちらも false の場合、ポインタ p とポインタ q等しいとみなされます。

ポインタ p がポインタ q と比較してより大きい場合、 p>=q, p>q, q<=p, q<p はいずれも true になり、 p<=q, p<q, q>=p, q>p はいずれも false になります。

2つのポインタが、より大きいとも等しいとも規定されていない場合、比較の結果は未規定です。 結果は非決定的であってもよく、プログラムの同じ実行における同じ被演算子を持つ同じ式の複数回の評価に対してであっても、一貫している必要はありません。

int x, y;
 
bool f(int* p, int* q) { return p < q; }
 
assert(f(&x, &y) == f(&x, &y)); // may fire in a conforming implementation

ユーザ定義の演算子に対するオーバーロード解決では、昇格された算術型 L および R のすべての組み合わせ (列挙型を含む) について、以下の関数シグネチャがオーバーロード解決に参加します。

bool operator<(L, R);
bool operator>(L, R);
bool operator<=(L, R);
bool operator>=(L, R);
bool operator==(L, R);
bool operator!=(L, R);

オブジェクトへのポインタまたは関数へのポインタまたは std::nullptr_t (C++14以前) であるすべての型 P について、以下の関数シグネチャがオーバーロード解決に参加します。

bool operator<(P, P);
bool operator>(P, P);
bool operator<=(P, P);
bool operator>=(P, P);
bool operator==(P, P);
bool operator!=(P, P);

メンバオブジェクトへのポインタまたはメンバ関数へのポインタまたは std::nullptr_t であるすべての型 MP について、以下の関数シグネチャがオーバーロード解決に参加します。

bool operator==(MP, MP);
bool operator!=(MP, MP);

[編集]

#include <iostream>
struct Foo  { int n1; int n2; };
union Union { int n; double d; };
int main()
{
    std::cout << std::boolalpha;
 
    char a[4] = "abc";
 
    char* p1 = &a[1];
    char* p2 = &a[2];
    std::cout << "Pointers to array elements: p1 == p2 " << (p1 == p2)
              << ", p1 < p2 "  << (p1 < p2) << '\n';
 
    Foo f;
    int* p3 = &f.n1;
    int* p4 = &f.n2;
    std::cout << "Pointers to members of a class: p3 == p4 " << (p3 == p4)
              << ", p3 < p4 "  << (p3 < p4) << '\n';
 
    Union u;
    int* p5 = &u.n;
    double* p6 = &u.d;
    std::cout << "Pointers to members of a union: p5 == (void*)p6 " << (p5 == (void*)p6)
              << ", p5 < p6 "  << (p5 < (void*)p6) << '\n';
}

出力:

Pointers to array elements: p1 == p2 false, p1 < p2 true
Pointers to members of a class: p3 == p4 false, p3 < p4 true
Pointers to members of a union: p5 == (void*)p6 true, p5 < p6 false

[編集] ノート

これらの演算子のグループは左結合のため、式 a<b<ca<(b<c)(a<b)&&(b<c) ではなく (a<b)<c と解析されます。

ユーザ定義の operator< に対する一般的な要件は厳密な弱い順序です。 これは特に Compare 型を使用する標準のアルゴリズムやコンテナ、 std::sortstd::max_elementstd::map などによって要求されます。

ランダムな起源の (例えば同じ配列のメンバを指すのではない) ポインタの比較の結果は未規定ですが、多くの処理系は、連続する仮想アドレス空間内のアドレスとして実装される場合、ポインタの厳密な全順序を提供します。 そうでない処理系 (例えばポインタのすべてのビットがメモリアドレスを表すのではないため比較するとき一部を無視しなければならないとか、ポインタと整数が1:1の関係でないため追加の計算が必要であるとか) は、そのような保証を持つ、ポインタに対する std::less の特殊化を提供します。 これにより、 std::setstd::map のような標準の連想コンテナで、ランダムな起源のポインタすべてをキーとして使用することが可能となります。

EqualityComparable かつ LessThanComparable である型について、 C++ 標準ライブラリは式 a == b の値である「等しい」と式 !(a < b) && !(b < a) の値である「同等」を区別します。

ポインタとヌルポインタ定数の比較は C++14 で削除されました。

void f(char * p)
{
  if (p > 0) { ... } // OK in C++98..C++11, does not compile in C++14
  if (p > nullptr) { ... } // OK in C++11, does not compile in C++14
}

三方比較

三方比較演算子は以下の形式を持ちます。

lhs <=> rhs (1)

この式は以下のようなオブジェクトを返します。

  • lhs < rhs であれば (a <=> b) < 0
  • lhs > rhs であれば (a <=> b) > 0
  • lhsrhs が等しい/同等であれば (a <=> b) == 0

被演算子の一方が bool 型で他方がそうでなければ、プログラムは ill-formed です。

被演算子がどちらも算術型の場合、または被演算子の一方がスコープなし列挙型で他方が整数型の場合、その被演算子に通常の算術変換が適用され、その後、

  • 整数型から浮動小数点型以外の縮小変換が要求される場合、プログラムは ill-formed です。
  • そうでなく、被演算子が整数型の場合、この演算子は std::strong_ordering 型の prvalue を返します。
  • 両方の被演算子が算術的に等しければ std::strong_ordering::equal
  • 第1引数が第2引数より算術的に小さければ std::strong_ordering::less
  • そうでなければ std::strong_ordering::greater
  • そうでなければ、被演算子は浮動小数点型であり、この演算子は std::partial_ordering 型の prvalue を返します。 式 a <=> b は以下の値を返します。
  • ab より小さければ std::partial_ordering::less
  • ab より大きければ std::partial_ordering::greater
  • ab と同等であれば std::partial_ordering::equivalent (-0 <=> +0 は同等です)。
  • いずれでもなければ std::partial_ordering::unordered (NaN <=> 任意の値 は unordered です)。

両方の被演算子が同じ列挙型 E である場合、この演算子は被演算子を E のベースとなる型に変換し、その変換した被演算子に <=> を適用した結果を返します。

被演算子の少なくとも一方がポインタまたはメンバへのポインタの場合、両方の被演算子を同じポインタ型に変換するために、配列からポインタへの変換、派生クラスから基底クラスへのポインタの変換、関数ポインタの変換、修飾子の変換が必要に応じて適用されます。

結果のポインタ型が関数ポインタ、メンバへのポインタ、または std::nullptr_t の場合、 p <=> qstd::strong_equality 型の prvalue を返します。

  • p == q であれば std::strong_equality::equal
  • p != q であれば std::strong_equality::unequal
  • これらのポインタ型に対して等しさの比較が未規定であれば未規定な結果。

結果のポインタ型がオブジェクトポインタ型の場合、 p <=> qstrong_ordering 型の prvalue を返します。

  • p == q であれば std::strong_ordering::equal
  • q > p であれば std::strong_ordering::less
  • p > q であれば std::strong_ordering::greater
  • これらのポインタ値に対して比較が未規定であれば (同じオブジェクトや配列を指すのではない場合など) 未規定な結果。

ユーザ定義の演算子に対するオーバーロード解決では、ポインタまたは列挙型 T について、以下の関数シグネチャがオーバーロード解決に参加します。

R operator<=>(T, T);

ただし R は上で定義されている順序カテゴリ型です。

メンバへのポインタ型または std::nullptr_t 型であるすべての T について、以下の関数シグネチャがオーバーロード解決に参加します。

std::strong_equality operator<=>(T, T);

ノート

三方比較はクラス型に対して自動的に生成できます。 デフォルト比較を参照してください。

両方の被演算子が配列の場合、配列型のクラスメンバを比較するときを除いて、三方比較は ill-formed です。

unsigned int i = 1;
auto r = -1 < i; // existing pitfall: returns ‘false’
auto r2 = -1 <=> i; // Error: narrowing conversion required


(C++20およびそれ以降)

[編集] 標準ライブラリ

比較演算子は標準ライブラリの多数のクラスでオーバーロードされています。

オブジェクトが同じ型を参照しているかどうか確認します
(std::type_infoのパブリックメンバ関数) [edit]
2つの error_code を比較します
(関数) [edit]
error_condition と error_code を比較します
(関数) [edit]
ペア内の値を辞書的に比較します
(関数テンプレート) [edit]
タプル内の値を辞書的に比較します
(関数テンプレート) [edit]
内容を比較します
(std::bitsetのパブリックメンバ関数) [edit]
2つのアロケータインスタンスを比較します
(std::allocatorのパブリックメンバ関数) [edit]
別の unique_ptr または nullptr と比較します
(関数テンプレート) [edit]
別の shared_ptr または nullptr と比較します
(関数テンプレート) [edit]
std::functionnullptr と比較します
(関数テンプレート) [edit]
2つの時間を比較します
(関数テンプレート) [edit]
2つの time point を比較します
(関数テンプレート) [edit]
2つの scoped_allocator_adaptor のインスタンスを比較します
(std::scoped_allocator_adaptorのパブリックメンバ関数) [edit]
ベースとなる std::type_info オブジェクトを比較します
(std::type_indexのパブリックメンバ関数) [edit]
2つの文字列を辞書的に比較します
(関数テンプレート) [edit]
2つのロケールオブジェクトが等しいかどうか比較します
(std::localeのパブリックメンバ関数) [edit]
array 内の値を辞書的に比較します
(関数テンプレート) [edit]
deque 内の値を辞書的に比較します
(関数テンプレート) [edit]
forward_list 内の値を辞書的に比較します
(関数テンプレート) [edit]
list 内の値を辞書的に比較します
(関数テンプレート) [edit]
vector 内の値を辞書的に比較します
(関数テンプレート) [edit]
map 内の値を辞書的に比較します
(関数テンプレート) [edit]
multimap 内の値を辞書的に比較します
(関数テンプレート) [edit]
set 内の値を辞書的に比較します
(関数テンプレート) [edit]
multiset 内の値を辞書的に比較します
(関数テンプレート) [edit]
unordered_map 内の値を比較します
(関数テンプレート) [edit]
unordered_multimap 内の値を比較します
(関数テンプレート) [edit]
unordered_set 内の値を比較します
(関数テンプレート) [edit]
unordered_multiset 内の値を比較します
(関数テンプレート) [edit]
queue 内の値を辞書的に比較します
(関数テンプレート) [edit]
stack 内の値を辞書的に比較します
(関数テンプレート) [edit]
ベースとなるイテレータを比較します
(関数テンプレート) [edit]
ベースとなるイテレータを比較します
(関数テンプレート) [edit]
2つの istream_iterator を比較します
(関数テンプレート) [edit]
2つの istreambuf_iterator を比較します
(関数テンプレート) [edit]
2つの複素数または複素数とスカラーを比較します
(関数テンプレート) [edit]
2つの valarray または valarray と値を比較します
(関数テンプレート) [edit]
擬似乱数エンジンの内部状態を比較します
(関数テンプレート) [edit]
2つの分布オブジェクトを比較します
(関数) [edit]
2つの sub_match オブジェクトを比較します
(関数テンプレート) [edit]
2つのマッチ結果の値を辞書的に比較します
(関数テンプレート) [edit]
2つの regex_iterator を比較します
(std::regex_iteratorのパブリックメンバ関数) [edit]
2つの regex_token_iterator を比較します
(std::regex_token_iteratorのパブリックメンバ関数) [edit]
2つの thread::id オブジェクトを比較します
(関数) [edit]

名前空間 rel_ops は汎用の演算子 !=, >, <=, >= を提供します。

ヘッダ <utility> で定義
名前空間 std::rel_ops で定義
ユーザ定義の operator== および operator< を元に比較演算子を自動生成します
(関数テンプレート) [edit]

[編集] 関連項目

演算子の優先順位

演算子オーバーロード

一般的な演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバアクセス その他

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

特殊な演算子

static_cast は型を別の関連する型に変換します。
dynamic_cast は継承階層内で変換します。
const_castcv 修飾子を追加または削除します。
reinterpret_cast は型を無関係の型に変換します。
C スタイルのキャストstatic_cast, const_cast, reinterpret_cast の混合によって型を別の型に変換します。
new は動的記憶域期間を持つオブジェクトを作成します。
delete は以前に new 式によって作成されたオブジェクトを破棄し、取得したメモリ領域を解放します。
sizeof は型のサイズを照会します。
sizeof...パラメータパックのサイズを照会します。 (C++11およびそれ以降)
typeid は型の型情報を照会します。
noexcept は式が例外を投げることができるかどうかを調べます。 (C++11およびそれ以降)
alignof は型のアライメント要件を照会します。 (C++11およびそれ以降)

比較演算子C言語リファレンス