比较运算符

比较运算符

C++

编译器支持

自由(freestanding)与宿主(hosted)

语言

标准库

标准库头文件

具名要求

特性测试宏 (C++20)

语言支持库

概念库 (C++20)

诊断库

内存管理库

元编程库 (C++11)

通用工具库

容器库

迭代器库

范围库 (C++20)

算法库

字符串库

文本处理库

数值库

日期和时间库

输入/输出库

文件系统库 (C++17)

并发支持库 (C++11)

执行控制库 (C++26)

技术规范

符号索引

外部库

[编辑] C++ 语言

通用主题

预处理器

注释

关键词

转义序列

流程控制

条件执行语句

if

switch

迭代语句(循环)

for

基于范围的 for (C++11)

while

do-while

跳转语句

continue - break

goto - return

函数

函数声明

Lambda 函数表达式

inline 说明符

动态异常规范 (直到 C++17*)

noexcept 说明符 (C++11)

异常

throw 表达式

try 块

catch 处理程序

命名空间

命名空间声明

命名空间别名

类型

基本类型

枚举类型

函数类型

类/结构体类型

联合类型

说明符

const/volatile

decltype (C++11)

auto (C++11)

constexpr (C++11)

consteval (C++20)

constinit (C++20)

存储期说明符

初始化

默认初始化

值初始化

零初始化

复制初始化

直接初始化

聚合初始化

列表初始化 (C++11)

常量初始化

引用初始化

表达式

值类别

求值顺序

运算符

运算符优先级

替代表示

字面量

布尔 - 整数 - 浮点

字符 - 字符串 - nullptr (C++11)

用户定义 (C++11)

工具

属性 (C++11)

类型

typedef 声明

类型别名声明 (C++11)

类型转换

隐式转换

static_cast

const_cast

显式转换

dynamic_cast

reinterpret_cast

内存分配

new 表达式

delete 表达式

类声明

构造函数

this 指针

访问说明符

friend 说明符

类特有的函数属性

虚函数

override 说明符 (C++11)

final 说明符 (C++11)

explicit (C++11)

static

特殊成员函数

默认构造函数

复制构造函数

移动构造函数 (C++11)

复制赋值

移动赋值 (C++11)

析构函数

模板

类模板

函数模板

模板特化

参数包 (C++11)

杂项

内联汇编

C++ 历史

[编辑] 表达式

通用

值类别

求值顺序

常量表达式

主表达式

Lambda 表达式 (C++11)

Requires 表达式 (C++20)

包索引表达式 (C++26)

潜在求值表达式

字面量

整数字面量

浮点数字面量

布尔字面量

字符字面量

转义序列

字符串字面量

空指针字面量 (C++11)

用户定义字面量 (C++11)

运算符

赋值运算符

递增和递减

算术运算符

逻辑运算符

比较运算符

成员访问运算符

其他运算符

new 表达式

delete 表达式

throw 表达式

alignof

sizeof

sizeof... (C++11)

typeid

noexcept (C++11)

折叠表达式 (C++17)

运算符的替代表示

优先级和结合性

运算符重载

默认比较 (C++20)

转换

隐式转换

显式转换

常用算术转换

用户定义转换

const_cast

static_cast

dynamic_cast

reinterpret_cast

[编辑]

比较参数。

运算符名称

语法

可重载

原型示例(对于 class T)

类定义内部

类定义外部

等于

a == b

bool T::operator==(const U& b) const;

bool operator==(const T& a, const U& b);

不等于

a != b

bool T::operator!=(const U& b) const;

bool operator!=(const T& a, const U& b);

小于

a < b

bool T::operator<(const U& b) const;

bool operator<(const T& a, const U& b);

大于

a > b

bool T::operator>(const U& b) const;

bool operator>(const T& a, const U& b);

小于或等于

a <= b

bool T::operator<=(const U& b) const;

bool operator<=(const T& a, const U& b);

大于或等于

a >= b

bool T::operator>=(const U& b) const;

bool operator>=(const T& a, const U& b);

三路比较 (C++20)

a <=> b

R T::operator<=>(const U& b) const;[1]

R operator<=>(const T& a, const U& b);[1]

注意

内建运算符返回 bool 的情况下,大多数用户定义的重载也返回 bool,这样用户定义的运算符就可以和内建运算符以相同的方式使用。但是,在用户定义的运算符重载中,任何类型都可以用作返回类型(包括 void)。 U 可以是任何类型,包括 T。

↑ 1.0 1.1 R 是 operator<=> 的返回类型(见下文)

目录

1 双路比较

1.1 关系运算符

1.2 相等运算符

1.3 内建双路比较运算符

1.4 内建算术比较

1.5 内建指针相等比较

1.6 内建指针关系比较

1.7 指针全序

1.8 重载

2 三路比较

2.1 重载

3 注意

4 标准库

5 缺陷报告

6 参阅

[编辑] 双路比较

双路比较运算符表达式具有以下形式

[编辑] 关系运算符

左操作数 < 右操作数

(1)

左操作数 > 右操作数

(2)

左操作数 <= 右操作数

(3)

左操作数 >= 右操作数

(4)

[编辑] 相等运算符

左操作数 == 右操作数

(5)

左操作数 != 右操作数

(6)

1) 如果 左操作数 小于 右操作数,返回 true,否则返回 false。

2) 如果 左操作数 大于 右操作数,返回 true,否则返回 false。

3) 如果 左操作数 小于或等于 右操作数,返回 true,否则返回 false。

4) 如果 左操作数 大于或等于 右操作数,返回 true,否则返回 false。

5) 如果 左操作数 等于 右操作数,返回 true,否则返回 false。

6) 如果 左操作数 不等于 右操作数,返回 true,否则返回 false。

[编辑] 内建双路比较运算符

对于内建双路比较运算符,左值到右值转换、数组到指针转换(C++26 前)和函数到指针转换会应用于左操作数和右操作数。

如果应用这些转换前 左操作数 和 右操作数 都具有数组类型,那么比较是被弃用的。

(C++20 起)(直到 C++26)

对于内建关系运算符,如果其中一个操作数是指针,则对另一个操作数执行数组到指针转换。

对于内建相等运算符,如果其中一个操作数是指针或空指针常量,则对另一个操作数执行数组到指针转换。

(C++26 起)

对于内建双路比较运算符,结果是 bool 纯右值。

[编辑] 内建算术比较

如果转换后的操作数都具有算术类型或枚举类型(有作用域或无作用域),则对两个操作数执行常规算术转换。在转换后比较值。

运行此代码

#include

int main()

{

static_assert(sizeof(unsigned char) < sizeof(int),

"Cannot compare signed and smaller unsigned properly");

int a = -1;

int b = 1;

unsigned int c = 1;

unsigned char d = 1;

std::cout << std::boolalpha

<< "Comparing two signed values:\n"

" -1 == 1 ? " << (a == b) << "\n"

" -1 < 1 ? " << (a < b) << "\n"

" -1 > 1 ? " << (a > b) << "\n"

"Comparing signed and unsigned:\n"

// may issue different-signedness warning:

" -1 == 1 ? " << (a == c) << "\n"

// may issue different-signedness warning:

" -1 < 1 ? " << (a < c) << "\n"

// may issue different-signedness warning:

" -1 > 1 ? " << (a > c) << "\n"

"Comparing signed and smaller unsigned:\n"

" -1 == 1 ? " << (a == d) << "\n"

" -1 < 1 ? " << (a < d) << "\n"

" -1 > 1 ? " << (a > d) << '\n';

}

输出

Comparing two signed values:

-1 == 1 ? false

-1 < 1 ? true

-1 > 1 ? false

Comparing signed and unsigned:

-1 == 1 ? false

-1 < 1 ? false

-1 > 1 ? true

Comparing signed and smaller unsigned:

-1 == 1 ? false

-1 < 1 ? true

-1 > 1 ? false

[编辑] 内建指针相等比较

相等运算符 == 和 != 转换后的操作数也可以有std::nullptr_t 类型、(C++11 起)指针类型或成员指针类型。

内建指针相等比较有三种可能的结果:相等、不相等和未指明。相等运算符对内建指针相等比较产生的值如下表所示:

比较结果p 和 q 的

产生的值

p == q

p != q

相等

true

false

不相等

false

true

未指定

未指明的 bool 值

如果转换后的 左操作数 和 右操作数 中至少有一个是指针,则对两个转换后的操作数执行指针转换、函数指针转换(C++17 起)和限定转换,以将它们转换为复合指针类型。这两个复合指针类型的指针按如下方式比较:

如果一个指针表示一个完整对象的地址,而另一个指针

表示另一个不同的非数组完整对象的尾后地址,或表示另一个不同的完整数组对象的最后一个元素之后一个位置的地址,

则比较的结果是未指明的。

否则,如果两个指针都是空指针,都指向同一个函数,或都表示相同的地址(即,它们指向同一个对象,或都是同一个对象的尾后指针),那么它们比较为相等。否则,指针比较为不相等。

如果转换后的 左操作数 和 右操作数 中至少有一个是成员指针,则对两个转换后的操作数执行成员指针转换、函数指针转换(C++17 起)和限定转换,以将它们转换为复合指针类型。这两个复合指针类型的成员指针按如下方式比较:

如果两个成员指针都是空成员指针值,它们比较为相等。如果两个成员指针中只有一个是空成员指针值,它们比较为不相等。如果其中任一是虚成员函数的指针,结果是未指明的。如果一个指向类 C1 的成员,而另一个指向另一个不同的类 C2 的成员,且两者都不是对方的基类,那么结果是未指明的。如果两者都指向同一个联合体的(可能不同的)成员,它们比较为相等。否则,如果通过一个假想的关联类类型的对象进行间接访问时,两个成员指针会引用同一个最终派生对象的同一个成员或同一个子对象,那么它们比较为相等,否则它们比较为不相等。

struct P {};

struct Q : P { int x; };

struct R : P { int x; };

int P::*bx = (int(P::*)) &Q::x;

int P::*cx = (int(P::*)) &R::x;

bool b1 = (bx == cx); // unspecified

struct B

{

int f();

};

struct L : B {};

struct R : B {};

struct D : L, R {};

int (B::*pb)() = &B::f;

int (L::*pl)() = pb;

int (R::*pr)() = pb;

int (D::*pdl)() = pl;

int (D::*pdr)() = pr;

bool x = (pdl == pdr); // false

bool y = (pb == pl); // true

两个类型为 std::nullptr_t 的操作数,或者一个操作数为 std::nullptr_t 类型而另一个为空指针常量的操作数,比较为相等。

(C++11 起)

[编辑] 内建指针关系比较

关系运算符 >、<、>= 和 <= 转换后的操作数也可以有指针类型。

内建指针关系比较对不相等的指针 p 和 q 有三种可能的结果:p 更大,q 更大和未指明。关系运算符对内建指针关系比较产生的值如下表所示:

比较结果p 和 q 的

产生的值

p > q

p < q

p >= q

p <= q

相等

false

false

true

true

p 更大

true

false

true

false

q 更大

false

true

false

true

未指定

未指明的 bool 值

如果转换后的 左操作数 和 右操作数 都是指针,则对两个转换后的操作数执行指针转换、函数指针转换(C++17 起)和限定转换,以将它们转换为复合指针类型。这两个复合指针类型的指针按如下方式比较:

如果指针比较为相等或相等比较结果是未指明的,则关系比较结果属于同一类别。否则(指针比较为不相等),如果任一指针不是对象指针,则结果是未指明的。否则(两个指针都指向对象),结果是根据与以下规则一致的偏序来定义的:

给定一个数组的两个不同元素 high 和 low,使得 high 的下标高于 low,如果一个指针指向 high(或 high 的子对象),另一个指针指向 low(或 low 的子对象),则前者比较为大于后者。如果一个指针指向数组的一个元素 elem(或 elem 的子对象),而另一个指针是同一数组的尾后指针,则尾后指针比较为大于另一个指针。如果一个指针指向一个完整对象、一个基类子对象或一个成员子对象 obj(或 obj 的子对象),而另一个指针是 obj 的尾后指针,则尾后指针比较为大于另一个指针。

如果两个指针指向同一个非联合体类类型对象的不同的非零大小(C++20 起)非静态数据成员且具有相同的成员访问权限(C++23 前),或者递归地指向这些成员的子对象,那么指向后面声明的成员的指针比较为大于另一个指针。否则,结果是未指明的。

[编辑] 指针全序

在每个程序中,都存在一个由实现定义的指针严格全序。这个严格全序与上面描述的偏序是一致的:未指明的结果变为由实现定义,而其他结果保持不变。

在以下情况下会应用严格全序的指针比较:

调用 std::less、std::greater、std::less_equal 和 std::greater_equal 的指针类型特化的 operator()。

从 std::less、std::greater、std::less_equal 和 std::greater_equal 的特化的 operator() 中调用内建运算符比较指针。

(C++14 起)

从 std::compare_three_way 的 operator() 中调用内建 operator<=> 比较指针。从 std::ranges::equal_to 和 std::ranges::not_equal_to 的 operator() 中调用内建 operator== 比较指针。从 std::ranges::less、std::ranges::greater、std::ranges::less_equal 和 std::ranges::greater_equal 的 operator() 中调用内建 operator< 比较指针。

(C++20 起)

[编辑] 重载

在针对用户定义运算符的重载决议中,对于每一对提升后的算术类型 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);

对于每种类型 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);

对于每种类型 MP(它是成员对象指针或成员函数指针或 std::nullptr_t(C++11 起)),以下函数签名参与重载决议:

bool operator==(MP, MP);

bool operator!=(MP, MP);

运行此代码

#include

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:\n"

<< "p1 == p2? " << (p1 == p2) << '\n'

<< "p1 < p2? " << (p1 < p2) << '\n';

Foo f;

int* p3 = &f.n1;

int* p4 = &f.n2;

std::cout << "Pointers to members of a class:\n"

<< "p3 == p4? " << (p3 == p4) << '\n'

<< "p3 < p4? " << (p3 < p4) << '\n';

Union u;

int* p5 = &u.n;

double* p6 = &u.d;

std::cout << "Pointers to members of a union:\n"

<< "p5 == (void*)p6? " << (p5 == (void*)p6) << '\n'

<< "p5 < (void*)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 < (void*)p6? false

三路比较

三路比较运算符表达式具有以下形式:

a <=> b

该表达式返回一个对象,使得:

若 a < b,则 (a <=> b) < 0, 若 a > b,则 (a <=> b) > 0, 若 a 和 b 相等/等价,则 (a <=> b) == 0。

如果其中一个操作数的类型为 bool 而另一个不是,则程序非良构。

如果两个操作数都具有算术类型,或者一个操作数具有无作用域枚举类型而另一个具有整数类型,则对操作数应用常规算术转换,然后

如果需要窄化转换(除了从整数类型到浮点类型的转换),则程序非良构。否则,如果操作数具有整数类型,则运算符产生一个 std::strong_ordering 类型的纯右值:

如果两个操作数在算术上相等,则为 std::strong_ordering::equal, 如果第一个操作数在算术上小于第二个操作数,则为 std::strong_ordering::less, 否则为 std::strong_ordering::greater。

否则,操作数具有浮点类型,运算符产生一个 std::partial_ordering 类型的纯右值。表达式 a <=> b 产生:

如果 a 小于 b,则为 std::partial_ordering::less, 如果 a 大于 b,则为 std::partial_ordering::greater, 如果 a 等价于 b(-0 <=> +0 是等价的),则为 std::partial_ordering::equivalent, (NaN <=> 任何值 是无序的)为 std::partial_ordering::unordered。

如果两个操作数具有相同的枚举类型 E,则运算符产生将操作数转换为 E 的底层类型并对转换后的操作数应用 <=> 的结果。

如果至少有一个操作数是对象指针或成员指针,则对两个操作数应用数组到指针转换、指针转换和限定转换,以将它们转换为复合指针类型。

对于转换后的指针操作数 p 和 q,p <=> q 返回一个 std::strong_ordering 类型的纯右值:

如果它们比较为相等,则为 std::strong_ordering::equal, 如果 q 比较为大于 p,则为 std::strong_ordering::less, 如果 p 比较为大于 q,则为 std::strong_ordering::greater,如果双路比较结果是未指明的,则结果未指明。

否则,程序格式错误。

重载

在针对用户定义运算符的重载决议中,对于指针或枚举类型 T,以下函数签名参与重载决议:

R operator<=>(T, T);

其中 R 是上面定义的排序类别类型。

运行此代码

#include

#include

int main()

{

double foo = -0.0;

double bar = 0.0;

auto res = foo <=> bar;

if (res < 0)

std::cout << "-0 is less than 0";

else if (res > 0)

std::cout << "-0 is greater than 0";

else if (res == 0)

std::cout << "-0 and 0 are equal";

else

std::cout << "-0 and 0 are unordered";

}

输出

-0 and 0 are equal

(C++20 起)

[编辑] 注意

因为比较运算符是左结合的,所以表达式 a < b < c 会被解析为 (a < b) < c,而不是 a < (b < c) 或 (a < b) && (b < c)。

运行此代码

#include

int main()

{

int a = 3, b = 2, c = 1;

std::cout << std::boolalpha

<< (a < b < c) << '\n' // true; maybe warning

<< ((a < b) < c) << '\n' // true

<< (a < (b < c)) << '\n' // false

<< ((a < b) && (b < c)) << '\n'; // false

}

对于用户定义的 operator<,一个常见的要求是严格弱序。特别是,使用 Compare 类型的标准算法和容器都需要这个要求,例如:std::sort、std::max_element、std::map 等。

指向同一类的不同非静态数据成员的指针的比较结果意味着,在三种成员访问模式中的每一种中,(C++23 前)非静态数据成员在内存中的位置按其声明顺序排列。

尽管比较随机来源(例如,并非都指向同一数组的成员)的指针的结果是未指定的,但许多实现为指针提供了严格全序,例如,如果它们被实现为连续虚拟地址空间内的地址。那些不提供严格全序的实现(例如,指针的某些位不是内存地址的一部分而必须在比较时被忽略,或者需要额外的计算,或者指针和整数之间不是一一对应的关系),会为指针提供 std::less 的特化,以保证这种全序关系。这使得可以将所有随机来源的指针作为键用在标准关联容器中,如 std::set 或 std::map。

对于同时满足 EqualityComparable 和 LessThanComparable 的类型,C++ 标准库区分了相等性 (equality) 和等价性 (equivalence)。相等性是表达式 a == b 的值,而等价性是表达式 !(a < b) && !(b < a) 的值。

指针与空指针常量之间的比较已通过 N3624 中包含的 CWG 问题 583 的解决方案移除。

运行此代码

void f(char* p)

{

if (p > 0) { /*...*/ } // Error with N3624, compiled before N3624

if (p > nullptr) { /*...*/ } // Error with N3624, compiled before N3624

}

int main() {}

可以为类类型自动生成三路比较,详见默认比较。

如果两个操作数都是数组,则三路比较是非法的。

unsigned int i = 1;

auto r = -1 < i; // existing pitfall: returns ‘false’

auto r2 = -1 <=> i; // Error: narrowing conversion required

特性测试宏

标准

特性

__cpp_impl_three_way_comparison

201907L

(C++20)

三路比较(编译器支持)

__cpp_lib_three_way_comparison

201907L

(C++20)

三路比较(库支持);向库中添加三路比较

[编辑] 标准库

标准库中的许多类都重载了比较运算符。

operator==operator!=(在 C++20 中移除)

检查对象是否引用相同的类型 (std::type_info 的公开成员函数) [编辑]

operator==operator!=operator(在 C++20 中移除)(在 C++20 中移除)(C++20)

比较两个 error_code (函数) [编辑]

operator==operator!=operator(在 C++20 中移除)(在 C++20 中移除)(C++20)

比较 error_condition 和 error_code (函数) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

字典序比较 pair 中的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典序比较 tuple 中的值 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较内容 (std::bitset 的公开成员函数) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个分配器实例 (std::allocator 的公开成员函数) [编辑]

operator==operator!=operatoroperator>=operator<=>(在 C++20 中删除)(C++20)

与另一个 unique_ptr 或与 nullptr 比较 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

与另一个 shared_ptr 或 nullptr 比较 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较 std::function 与 nullptr (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++11)(C++11)(C++20 中移除)(C++11)(C++11)(C++11)(C++11)(C++20)

比较两个 durations (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++11)(C++11)(C++20 中移除)(C++11)(C++11)(C++11)(C++11)(C++20)

比较两个时间点 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个 scoped_allocator_adaptor 对象 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(在 C++20 中删除)(C++20)

比较底层的 std::type_info 对象 (std::type_index 的公开成员函数) [编辑]

operator==operator!=operatoroperator<=operator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典序比较两个字符串 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

locale 对象之间的相等性比较 (std::locale 的公开成员函数) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++11)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++20)

按字典序比较两个 array 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典序比较两个 deque 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++11)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++11)(C++20 中移除)(C++20)

按字典顺序比较两个 forward_list 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

以字典序比较两个 list 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

字典序比较两个 vector 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典顺序比较两个 map 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

字典序比较两个 multimap 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典顺序比较两个 set 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典序比较两个 multiset 的值 (函数模板) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较 unordered_map 中的值 (函数模板) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较 unordered_multimap 中的值 (函数模板) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较 unordered_set 中的值 (函数模板) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较 unordered_multiset 中的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20)

按字典顺序比较两个 queue 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20)

按字典序比较两个 stack 的值 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20)

比较底层迭代器 (函数模板) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++11)(C++11)(C++20 中移除)(C++11)(C++11)(C++11)(C++11)(C++20)

比较底层迭代器 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个 istream_iterator (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个 istreambuf_iterator (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个复数或一个复数和一个标量 (函数模板) [编辑]

operator==operator!=operatoroperator>=

比较两个 valarray 或一个 valarray 与一个值 (函数模板) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较两个伪随机数引擎的内部状态 (函数) [编辑]

operator==operator!=(C++11起)(C++11起)(C++20中移除)

比较两个分布对象 (函数) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

将 sub_match 与另一个 sub_match、字符串或字符进行比较 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

按字典顺序比较两个匹配结果中的值 (函数模板) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个 regex_iterator (std::regex_iterator 的公开成员函数) [编辑]

operator==operator!=(在 C++20 中移除)

比较两个 regex_token_iterator (std::regex_token_iterator 的公开成员函数) [编辑]

operator==operator!=operatoroperator>=operator<=>(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

比较两个 thread::id 对象 (函数) [编辑]

命名空间 std::rel_ops 提供了通用的运算符 !=、>、<= 和 >=

在头文件 中定义

定义于命名空间 std::rel_ops

operator!=operator>operator<=operator>=(C++20 中已弃用)

基于用户定义的 operator== 和 operator< 自动生成比较运算符 (函数模板) [编辑]

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告

应用于

发布时的行为

正确的行为

CWG 583(N3624)

C++98

所有六个比较运算符都可以用于比较指针与空指针常量

只允许相等运算符被允许

CWG 661

C++98

算术比较的实际语义(例如1 < 2 产生 true 还是 false)未被指定

添加了规范

CWG 879

C++98

指向函数类型的指针和指向void 的指针没有内建比较

为这些指针添加了比较规范规范

CWG 1596

C++98

非数组对象仅在指针算术中被认为属于大小为一的数组

此规则也应用于比较

CWG 1598

C++98

指向不同类成员的两个指针,且两个类都不是对方的基类,它们不会比较为相等,即使所指向成员的偏移量可能相同

结果为未指定在这种情况下

CWG 1858

C++98

不清楚指向同一联合体中不同成员的两个成员指针是否像指向同一成员一样比较为相等

在这种情况下它们比较为相等

CWG 2419

C++98

指向非数组对象的指针仅在通过 & 获取时,才在指针比较中被视为指向大小为 1 的数组的第一个元素

适用于所有指向非数组对象的指针

CWG 2526

C++98

指向 void 的指针和函数指针的关系比较(>, >=, <, <=)的定义被 N3624 移除了

恢复

CWG 2796

C++17

在内建指针关系比较中,函数指针转换未对转换后的指针操作数执行

在这种情况下执行这些转换

[编辑] 参阅

运算符优先级

运算符重载

Compare (具名要求)

常见运算符

赋值

递增递减

算术

逻辑

比较

成员访问

其他

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

++a

--aa++a--

+a

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

!aa && ba || b

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

a[...]

*a

&aa->ba.ba->*ba.*b

函数调用a(...)

逗号a, b

条件a ? b : c

特殊运算符

static_cast 将一种类型转换为另一种相关类型

dynamic_cast 在继承层次结构内进行转换

const_cast 添加或移除 cv-限定符

reinterpret_cast 将类型转换为不相关类型

C 风格转型通过混合使用 static_cast、const_cast 和 reinterpret_cast 将一种类型转换为另一种

new 创建具有动态存储期的对象

delete 销毁先前由 new 表达式创建的对象并释放获得的内存区域

sizeof 查询类型的大小

sizeof... 查询 包 的大小 (C++11 起)

typeid 查询类型的类型信息

noexcept 检查表达式是否可以抛出异常 (C++11 起)

alignof 查询类型的对齐要求 (C++11 起)

C 文档中关于比较运算符的内容

相关推荐

bat365app手机版下载 dnf妖刀和无用哪个好

dnf妖刀和无用哪个好

📅 08-16 👁️ 740
bat365app手机版下载 什么时候有流星(什么时候有流星雨2025几月几日几点)
365bet下注网站 挥霍 (Consuming) - [FM]禁忌魔法 (Forbidden Magic) - MC百科