命名空间
变体
操作

算术运算符

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++11 中弃用*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储持续性说明符
初始化
 
 

返回特定算术运算的结果。

运算符名称 语法 原型示例 (对于 class T)
在类定义内 在类定义外
一元加 +a T T::operator+() const; T operator+(const T& a);
一元减 -a T T::operator-() const; T operator-(const T& a);
加法 a + b T T::operator+(const T2& b) const; T operator+(const T& a, const T2& b);
减法 a - b T T::operator-(const T2& b) const; T operator-(const T& a, const T2& b);
乘法 a * b T T::operator*(const T2& b) const; T operator*(const T& a, const T2& b);
除法 a / b T T::operator/(const T2& b) const; T operator/(const T& a, const T2& b);
求余 a % b T T::operator%(const T2& b) const; T operator%(const T& a, const T2& b);
按位非 ~a T T::operator~() const; T operator~(const T& a);
按位与 a & b T T::operator&(const T2& b) const; T operator&(const T& a, const T2& b);
按位或 a | b T T::operator|(const T2& b) const; T operator|(const T& a, const T2& b);
按位异或 a ^ b T T::operator^(const T2& b) const; T operator^(const T& a, const T2& b);
按位左移 a << b T T::operator<<(const T2& b) const; T operator<<(const T& a, const T2& b);
按位右移 a >> b T T::operator>>(const T2& b) const; T operator>>(const T& a, const T2& b);
注意
  • 此表中的所有运算符都是可重载的
  • 所有内置运算符都返回值,并且大多数用户定义的重载也返回值,以便用户定义的运算符可以像内置运算符一样使用。但是,在用户定义的运算符重载中,任何类型都可以用作返回类型(包括 void)。特别是,流插入和流提取运算符 operator<<operator>> 的重载返回 T&
  • T2 可以是任何类型,包括 T

目录

[编辑] 通用解释

所有内置算术运算符都计算特定算术运算的结果并返回其结果。参数不会被修改。

[编辑] 转换

如果传递给内置算术运算符的操作数是整型或无作用域枚举类型,则在任何其他操作之前(但在左值到右值转换之后,如果适用),操作数会经历整型提升。如果操作数具有数组或函数类型,则应用数组到指针函数到指针转换。

对于二元运算符(移位运算符除外),如果提升后的操作数具有不同的类型,则应用常用算术转换

[编辑] 溢出

无符号整数算术始终以 模 2n
执行,其中 n 是该特定整数中的位数。例如,对于 unsigned int,将 1 加到 UINT_MAX 得到 0,从 0 减去 1 得到 UINT_MAX

当有符号整数算术运算溢出时(结果不适合结果类型),行为是未定义的,— 这种操作的可能表现形式包括

  • 它根据表示规则(通常为补码)环绕,
  • 它会陷入陷阱 — 在某些平台上或由于编译器选项(例如 GCC 和 Clang 中的 -ftrapv),
  • 它会饱和到最小值或最大值(在许多 DSP 上),
  • 它完全被编译器优化掉

[编辑] 浮点环境

如果支持 #pragma STDC FENV_ACCESS 并设置为 ON,则所有浮点算术运算符都遵守当前的浮点舍入方向,并按照 math_errhandling 中的规定报告浮点算术错误,除非是 静态初始化器 的一部分(在这种情况下,不会引发浮点异常,并且舍入模式为舍入到最接近的值)。

[编辑] 浮点收缩

除非支持 #pragma STDC FP_CONTRACT 并设置为 OFF,否则所有浮点算术运算都可以执行,就好像中间结果具有无限范围和精度一样,即允许省略舍入误差和浮点异常的优化。例如,C++ 允许使用单个融合乘加 CPU 指令实现 (x * y) + z,或将 a = x * x * x * x; 优化为 tmp = x * x; a = tmp * tmp

与收缩无关,浮点算术的中间结果可能具有与其类型指示的范围和精度不同的范围和精度,请参阅 FLT_EVAL_METHOD

形式上,C++ 标准不保证浮点运算的精度。

[编辑] 一元算术运算符

一元算术运算符表达式具有以下形式

+ 表达式 (1)
- 表达式 (2)
1) 一元加(提升)。
2) 一元减(取反)。

一元 +- 运算符的优先级高于所有二元算术运算符,因此 表达式 不能包含顶层二元算术运算符。这些运算符从右到左结合

+a - b; // equivalent to (+a) - b, NOT +(a - b)
-c + d; // equivalent to (-c) + d, NOT -(c + d)
 
+-e; // equivalent to +(-e), the unary + is a no-op if “e” is a built-in type
     // because any possible promotion is performed during negation already

[编辑] 内置一元算术运算符

1) 对于内置一元加运算符,表达式 必须是算术、无作用域枚举或指针类型的纯右值。如果 表达式 具有整型或无作用域枚举类型,则对其执行整型提升。结果的类型是 表达式 的(可能提升后的)类型。
内置提升的结果是 表达式 的值。如果操作数是提升后的整型或指针类型的纯右值,则内置一元运算是空操作。否则,操作数的类型或值类别会因整型提升或左值到右值、数组到指针、函数到指针或用户定义的转换而改变。例如,char 在一元加表达式中转换为 int ,非泛型无捕获 lambda 表达式 转换为函数指针(自 C++11 起)
2) 对于内置一元减运算符,表达式 必须是算术或无作用域枚举类型的纯右值。对 表达式 执行整型提升。结果的类型是 表达式 的提升类型的类型。
内置取反的结果是提升后的 表达式 的负数。对于无符号 a-a 的值是 2N
-a
,其中 N 是提升后的位数。
  • 换句话说,结果是操作数的补码(其中操作数和结果都被视为无符号数)。

[编辑] 重载

在针对用户定义的运算符的重载解析中,对于每个 cv-非限定的提升算术类型 A 和每种类型 T,以下函数签名参与重载解析

A operator+(A)
T* operator+(T*)
A operator-(A)
#include <iostream>
 
int main()
{
    char c = 0x6a;
    int n1 = 1;
    unsigned char n2 = 1;
    unsigned int n3 = 1;
    std::cout << "char: " << c << " int: " << +c << "\n"
                 "-1, where 1 is signed: " << -n1 << "\n"
                 "-1, where 1 is unsigned char: " << -n2 << "\n"
                 "-1, where 1 is unsigned int: " << -n3 << '\n';
    char a[3];
    std::cout << "size of array: " << sizeof a << "\n"
                 "size of pointer: " << sizeof +a << '\n';
}

可能输出

char: j int: 106
-1, where 1 is signed: -1
-1, where 1 is unsigned char: -1
-1, where 1 is unsigned int: 4294967295
size of array: 3
size of pointer: 8

[编辑] 加法运算符

加法运算符表达式具有以下形式

左操作数 + 右操作数 (1)
左操作数 - 右操作数 (2)
1) 二元加(加法)。
2) 二元减(减法)。

二元 +- 运算符的优先级高于除 */% 之外的所有其他二元算术运算符。这些运算符从左到右结合

a + b * c;  // equivalent to a + (b * c),  NOT (a + b) * c
d / e - f;  // equivalent to (d / e) - f,  NOT d / (e - f)
g + h >> i; // equivalent to (g + h) >> i, NOT g + (h >> i)
 
j - k + l - m; // equivalent to ((j - k) + l) - m

[编辑] 内置加法运算符

对于内置二元加法和二元减法运算符,左操作数右操作数 都必须是纯右值,并且必须满足以下条件之一

  • 两个操作数都具有算术或无作用域枚举类型。在这种情况下,对两个操作数执行常用算术转换
  • 只有一个操作数具有整型或无作用域枚举类型。在这种情况下,对该操作数应用整型提升。

在本节的其余描述中,“操作数”、“左操作数”和“右操作数”指的是转换后或提升后的操作数。

1) 对于内置加法,必须满足以下条件之一
  • 两个操作数都具有算术类型。在这种情况下,结果是操作数的和。
  • 一个操作数是指向完全定义的对象类型的指针,另一个操作数具有整型。在这种情况下,将整型值添加到指针(参见指针算术)。
2) 对于内置减法,必须满足以下条件之一
  • 两个操作数都具有算术类型。在这种情况下,结果是从 左操作数 中减去 右操作数 得到的差值。
  • 左操作数 是指向完全定义的对象类型的指针,而 右操作数 具有整型。在这种情况下,从指针中减去整型值(参见指针算术)。
  • 两个操作数都是指向同一完全定义对象类型的 cv 限定或 cv 非限定版本的指针。在这种情况下,从 左操作数 中减去 右操作数(参见指针算术)。

如果两个操作数都具有浮点类型,并且该类型支持 IEEE 浮点算术(参见 std::numeric_limits::is_iec559

  • 如果一个操作数是 NaN,则结果为 NaN。
  • 无穷减无穷是 NaN,并且会引发 FE_INVALID
  • 无穷加负无穷是 NaN,并且会引发 FE_INVALID

[编辑] 指针算术

当将具有整型类型 的表达式 J 添加到指针类型表达式 P 或从中减去时,结果具有 P 的类型。

  • 如果 P 的计算结果为空指针值,并且 J 的计算结果为 0,则结果为空指针值。
  • 否则,如果 P 指向具有 n 个元素的数组对象 x 的第 i 个元素,给定 J 的值为 j,则 P 的加法或减法如下
  • 表达式 P + JJ + P
  • 指向 i+jth element of x 如果 i + j[0n) 范围内,并且
  • 是指向 x 的最后一个元素之后的位置的指针,如果 i + jn
  • 表达式 P - J
  • 指向 i-jth element of x 如果 i - j[0n) 范围内,并且
  • 是指向 x 的最后一个元素之后的位置的指针,如果 i - jn
  • 其他 j 值会导致未定义行为。
  • 否则,如果 P 指向一个完整的对象、一个基类子对象或一个成员子对象 y,给定 J 的值为 j,则 P 的加法或减法运算如下
  • 表达式 P + JJ + P
  • 指向 y 如果 j0,并且
  • 是指向 y 结尾之后的位置的指针,如果 j1
  • 表达式 P - J
  • 指向 y 如果 j0,并且
  • 是指向 y 结尾之后的位置的指针,如果 j-1
  • 其他 j 值会导致未定义行为。
  • 否则,如果 P 是指向对象 z 结尾之后的位置的指针,给定 J 的值为 j
  • 如果 z 是具有 n 个元素的数组对象,则 P 的加法或减法运算如下
  • 表达式 P + JJ + P
  • 指向 n+jth element of z 如果 n + j[0n) 范围内,并且
  • 是指向 z 的最后一个元素之后的位置的指针,如果 j0
  • 表达式 P - J
  • 指向 n-jth element of z 如果 n - j[0n) 范围内,并且
  • 是指向 z 的最后一个元素之后的位置的指针,如果 j0
  • 其他 j 值会导致未定义行为。
  • 否则,P 的加法或减法运算如下
  • 表达式 P + JJ + P
  • 指向 z 如果 j-1,并且
  • 是指向 z 结尾之后的位置的指针,如果 j0
  • 表达式 P - J
  • 指向 z 如果 j1,并且
  • 是指向 z 结尾之后的位置的指针,如果 j0
  • 其他 j 值会导致未定义行为。
  • 否则,行为是未定义的。

当两个指针表达式 PQ 相减时,结果的类型是 std::ptrdiff_t

  • 如果 PQ 都求值为空指针值,则结果为 0
  • 否则,如果 PQ 分别指向同一个数组对象 x 的第 i 个和第 j 个数组元素,则表达式 P - Q 的值为 i − j
  • 如果 i − j 不能用 std::ptrdiff_t 表示,则行为是未定义的。
  • 否则,如果 PQ 指向同一个完整的对象、基类子对象或成员子对象,则结果为 0
  • 否则,行为是未定义的。

这些指针算术运算符允许指针满足 LegacyRandomAccessIterator 的要求。

对于加法和减法,如果 PQ 具有类型 “pointer to (possibly cv-qualified) T”,其中 T 和数组元素类型不是 相似的,则行为是未定义的

int arr[5] = {1, 2, 3, 4, 5};
unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1);
unsigned int k = *p; // OK, the value of “k” is 2
unsigned int *q = p + 1; // undefined behavior: “p” points to int, not unsigned int

[编辑] 重载

针对用户定义的运算符的重载决议中,对于每对提升的算术类型 LR 以及对于每个对象类型 T,以下函数签名参与重载决议

LR operator+(L, R)
LR operator-(L, R)
T* operator+(T*, std::ptrdiff_t)
T* operator+(std::ptrdiff_t, T*)
T* operator-(T*, std::ptrdiff_t)
std::ptrdiff_t operator-(T*, T*)

其中 LRLR常用算术转换 的结果。

#include <iostream>
 
int main()
{
    char c = 2;
    unsigned int un = 2;
    int n = -10;
    std::cout << " 2 + (-10), where 2 is a char    = " << c + n << "\n"
                 " 2 + (-10), where 2 is unsigned  = " << un + n << "\n"
                 " -10 - 2.12  = " << n - 2.12 << '\n';
 
    char a[4] = {'a', 'b', 'c', 'd'};
    char* p = &a[1];
    std::cout << "Pointer addition examples: " << *p << *(p + 2)
              << *(2 + p) << *(p - 1) << '\n';
    char* p2 = &a[4];
    std::cout << "Pointer difference: " << p2 - p << '\n';
}

输出

 2 + (-10), where 2 is a char    = -8
 2 + (-10), where 2 is unsigned  = 4294967288
 -10 - 2.12  = -12.12
Pointer addition examples: bdda
Pointer difference: 3

[编辑] 乘法运算符

乘法运算符表达式具有以下形式

lhs * rhs (1)
lhs / rhs (2)
lhs % rhs (3)
1) 乘法。
2) 除法。
3) 取余。

乘法运算符的优先级高于所有其他二元算术运算符。 这些运算符从左到右结合

a + b * c;  // equivalent to a + (b * c),  NOT (a + b) * c
d / e - f;  // equivalent to (d / e) - f,  NOT d / (e - f)
g % h >> i; // equivalent to (g % h) >> i, NOT g % (h >> i)
 
j * k / l % m; // equivalent to ((j * k) / l) % m

[编辑] 内置乘法运算符

对于内置的乘法和除法运算符,两个操作数都必须具有算术或无作用域枚举类型。 对于内置的取余运算符,两个操作数都必须具有整数或无作用域枚举类型。 常用算术转换 在两个操作数上执行。

在本节的其余描述中,“操作数”,lhsrhs 指的是转换后的操作数。

1) 内置乘法的结果是操作数的乘积。
如果两个操作数都具有浮点类型,并且该类型支持 IEEE 浮点运算(参见 std::numeric_limits::is_iec559
  • NaN 乘以任何数字都得到 NaN。
  • 无穷大乘以零得到 NaN,并引发 FE_INVALID
2) 内置除法的结果是 lhs 除以 rhs。 如果 rhs 为零,则行为是未定义的。
如果两个操作数都具有整数类型,则结果是代数商(执行整数除法):商向零截断(小数部分被丢弃)。
如果两个操作数都具有浮点类型,并且该类型支持 IEEE 浮点运算(参见 std::numeric_limits::is_iec559
  • 如果一个操作数是 NaN,则结果为 NaN。
  • 将非零数除以 ±0.0 会给出正确符号的无穷大,并引发 FE_DIVBYZERO
  • 0.0 除以 0.0 得到 NaN,并引发 FE_INVALID
3) 内置取余的结果是 lhs 除以 rhs 的整数除法的余数。 如果 rhs 为零,则行为是未定义的。
如果 a / b 可在结果类型中表示,则 (a / b) * b + a % b == a
如果 a / b 不可在结果类型中表示,则 a / ba % b 的行为都是未定义的(这意味着在补码系统上 INT_MIN % -1 是未定义的)。

注意:在 CWG issue 614 解决之前 (N2757),如果二元运算符 % 的一个或两个操作数为负数,则余数的符号是实现定义的,因为它取决于整数除法的舍入方向。 在这种情况下,函数 std::div 提供了明确定义的行为。

注意:对于浮点余数,请参见 std::remainderstd::fmod

[编辑] 重载

针对用户定义的运算符的重载决议中,对于每对提升的算术类型 LARA 以及对于每对提升的整数类型 LIRI,以下函数签名参与重载决议

LRA operator*(LA, RA)
LRA operator/(LA, RA)
LRI operator%(LI, RI)

其中 LRxLxRx常用算术转换 的结果。

#include <iostream>
 
int main()
{
    char c = 2;
    unsigned int un = 2;
    int  n = -10;
    std::cout << "2 * (-10), where 2 is a char    = " << c * n << "\n"
                 "2 * (-10), where 2 is unsigned  = " << un * n << "\n"
                 "-10 / 2.12  = " << n / 2.12 << "\n"
                 "-10 / 21  = " << n / 21 << "\n"
                 "-10 % 21  = " << n % 21 << '\n';
}

输出

2 * (-10), where 2 is a char    = -20
2 * (-10), where 2 is unsigned  = 4294967276
-10 / 2.12  = -4.71698
-10 / 21  = 0
-10 % 21  = -10

[编辑] 位逻辑运算符

位逻辑运算符表达式具有以下形式

~ rhs (1)
lhs & rhs (2)
lhs | rhs (3)
lhs ^ rhs (4)
1) 位非。
2) 位与。
3) 位或。
4) 位异或。

位非运算符的优先级高于所有二元算术运算符。 它从右到左结合

~a - b; // equivalent to (~a) - b, NOT ~(a - b)
~c * d; // equivalent to (~c) * d, NOT ~(c * d)
 
~-e; // equivalent to ~(-e)

~ 后跟 类型名称decltype 说明符(自 C++11 起) 时,语法上存在歧义:它可以是 operator~ 或启动 析构函数 标识符)。 歧义通过将 ~ 视为 operator~ 来解决。 ~ 只能在语法上无效形成 operator~ 的地方启动析构函数标识符。

所有其他位逻辑运算符的优先级都低于所有其他二元算术运算符。 位与的优先级高于位异或,位异或的优先级高于位或。 它们从左到右结合

a & b * c;  // equivalent to a & (b * c),  NOT (a & b) * c
d / e ^ f;  // equivalent to (d / e) ^ f,  NOT d / (e ^ f)
g << h | i; // equivalent to (g << h) | i, NOT g << (h | i)
 
j & k & l; // equivalent to (j & k) & l
m | n ^ o  // equivalent to m | (n ^ o)

[编辑] 内置位逻辑运算符

对于内置的位非运算符,rhs 必须是整数或无作用域枚举类型的纯右值,并且对 rhs 执行整数提升。 对于其他内置位逻辑运算符,两个操作数都必须具有整数或无作用域枚举类型,并且 常用算术转换 在两个操作数上执行。

在本节的其余描述中,“操作数”、“左操作数”和“右操作数”指的是转换后或提升后的操作数。

1) 给定操作数为 x,内置位非运算的结果为 r。 对于 x 的二进制表示的每个系数 x_ir 的二进制表示的相应系数 r_i1 如果 x_i0,否则为 0
  • 换句话说,结果是操作数的反码(其中操作数和结果被视为无符号)。
结果 r 的类型是操作数 x 的类型。
2-4) 给定操作数分别为 xy,内置二元位逻辑运算的结果为 r。 对于 xy 的二进制表示的每对系数 x_iy_ir 的二进制表示的相应系数 r_i
2) 1 如果 x_iy_i 都是 1,否则为 0
3) 1 如果 x_iy_i 中至少有一个是 1,否则为 0
4) 1 如果 x_iy_i 中恰好有一个(但不是两个)是 1,否则为 0
结果 r 的类型是操作数 xy 的类型。

[编辑] 重载

针对用户定义的运算符的重载决议中,对于每对提升的整数类型 LR,以下函数签名参与重载决议

R operator~(R)
LR operator&(L, R)
LR operator^(L, R)
LR operator|(L, R)

其中 LRLR常用算术转换 的结果。

#include <bitset>
#include <cstdint>
#include <iomanip>
#include <iostream>
 
int main()
{
    std::uint16_t mask = 0x00f0;
    std::uint32_t x0 = 0x12345678;
    std::uint32_t x1 = x0 | mask;
    std::uint32_t x2 = x0 & ~mask;
    std::uint32_t x3 = x0 & mask;
    std::uint32_t x4 = x0 ^ mask;
    std::uint32_t x5 = ~x0;
    using bin16 = std::bitset<16>;
    using bin32 = std::bitset<32>;
    std::cout << std::hex << std::showbase
              << "Mask: " << mask << std::setw(49) << bin16(mask) << "\n"
                 "Value: " << x0 << std::setw(42) << bin32(x0) << "\n"
                 "Setting bits: " << x1 << std::setw(35) << bin32(x1) << "\n"
                 "Clearing bits: " << x2 << std::setw(34) << bin32(x2) << "\n"
                 "Selecting bits: " << x3 << std::setw(39) << bin32(x3) << "\n"
                 "XOR-ing bits: " << x4 << std::setw(35) << bin32(x4) << "\n"
                 "Inverting bits: " << x5 << std::setw(33) << bin32(x5) << '\n';
}

输出

Mask: 0xf0                                 0000000011110000
Value: 0x12345678          00010010001101000101011001111000
Setting bits: 0x123456f8   00010010001101000101011011111000
Clearing bits: 0x12345608  00010010001101000101011000001000
Selecting bits: 0x70       00000000000000000000000001110000
XOR-ing bits: 0x12345688   00010010001101000101011010001000
Inverting bits: 0xedcba987 11101101110010111010100110000111

[编辑] 位移位运算符

位移位运算符表达式具有以下形式

lhs << rhs (1)
lhs >> rhs (2)
1) 位左移。
2) 位右移。

位移位运算符的优先级高于位逻辑运算符,但低于加法和乘法运算符。 这些运算符从左到右结合

a >> b * c;  // equivalent to a >> (b * c),  NOT (a >> b) * c
d << e & f;  // equivalent to (d << e) & f,  NOT d << (e & f)
 
g << h >> i; // equivalent to (g << h) >> i, NOT g << (h >> i)

[编辑] 内置位移位运算符

对于内置位移位运算符,两个操作数都必须是整数或无作用域枚举类型的纯右值。 整数提升在两个操作数上执行。

在本节的其余描述中,“操作数”,ablhsrhs 指的是转换或提升后的操作数。

如果 rhs 的值为负数或不小于 lhs 中的位数,则行为是未定义的。

对于无符号 aa << b 的值是 a * 2b
的值,对 2N
取模,其中 N 是返回类型中的位数(即,执行位左移,并且移出目标类型的位被丢弃)。

对于有符号且非负的 a,如果 a * 2b
可在返回类型的无符号版本中表示,那么该值 转换 为有符号,就是 a << b 的值(这使得创建 INT_MIN1 << 31 是合法的); 否则,行为是未定义的。

对于负数 aa << b 的行为是未定义的。

对于无符号 a 以及有符号且非负的 aa >> b 的值是 a/2b
的整数部分。

对于负数 aa >> b 的值是实现定义的(在大多数实现中,这执行算术右移,因此结果保持为负数)。

(直到 C++20)

a << b 的值是与 a * 2b
2N
同余的唯一值,其中 N 是返回类型中的位数(即,执行位左移,并且移出目标类型的位被丢弃)。

a >> b 的值是 a/2b
,向负无穷大舍入(换句话说,有符号 a 上的右移是算术右移)。

(自 C++20 起)

结果的类型是 lhs 的类型。

[编辑] 重载

针对用户定义的运算符的重载决议中,对于每对提升的整数类型 LR,以下函数签名参与重载决议

L operator<<(L, R)
L operator>>(L, R)
#include <iostream>
 
enum { ONE = 1, TWO = 2 };
 
int main()
{
    std::cout << std::hex << std::showbase;
    char c = 0x10;
    unsigned long long ull = 0x123;
    std::cout << "0x123 << 1 = " << (ull << 1) << "\n"
                 "0x123 << 63 = " << (ull << 63) << "\n" // overflow in unsigned
                 "0x10 << 10 = " << (c << 10) << '\n';   // char is promoted to int
    long long ll = -1000;
    std::cout << std::dec << "-1000 >> 1 = " << (ll >> ONE) << '\n';
}

输出

0x123 << 1 = 0x246
0x123 << 63 = 0x8000000000000000
0x10 << 10 = 0x4000
-1000 >> 1 = -500

[编辑] 标准库

算术运算符为许多标准库类型重载。

[编辑] 一元算术运算符

实现一元 + 和一元 -
std::chrono::duration<Rep,Period> 的公共成员函数) [编辑]
将一元运算符应用于复数
(函数模板) [编辑]
将一元算术运算符应用于 valarray 的每个元素
std::valarray<T> 的公共成员函数) [编辑]

[编辑] 加法运算符

执行涉及时间点的加法和减法运算
(函数模板) [编辑]
实现以 duration 作为参数的算术运算
(函数模板) [编辑]
添加或减去 year_month_day 和一些年或月
(函数) [编辑]
连接两个字符串,一个字符串和一个 char,或一个字符串和一个 string_view
(函数模板) [编辑]
递增或递减迭代器
std::reverse_iterator<Iter> 的公共成员函数)
递增或递减迭代器
std::move_iterator<Iter> 的公共成员函数)
对两个复数值或一个复数和一个标量执行复数算术运算
(函数模板) [编辑]
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值
(函数模板) [编辑]

[编辑] 乘法运算符

实现以 duration 作为参数的算术运算
(函数模板) [编辑]
对两个复数值或一个复数和一个标量执行复数算术运算
(函数模板) [编辑]
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值
(函数模板) [编辑]

[编辑] 位逻辑运算符

执行二元 AND、OR、XOR 和 NOT
std::bitset<N> 的公共成员函数) [编辑]
对 bitset 执行二元逻辑运算
(函数模板) [编辑]
将一元算术运算符应用于 valarray 的每个元素
std::valarray<T> 的公共成员函数)
将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值
(函数模板)

[编辑] 位移位运算符

将二元运算符应用于两个 valarray 的每个元素,或一个 valarray 和一个值
(函数模板)
执行二元左移和右移
std::bitset<N> 的公共成员函数)

[编辑] 流插入/提取运算符

在整个标准库中,位移位运算符通常与 I/O 流 (std::ios_base& 或其派生类之一) 重载,作为左操作数和返回类型。 这种运算符被称为流插入流提取运算符

提取格式化数据
std::basic_istream<CharT,Traits> 的公共成员函数) [编辑]
提取字符和字符数组
(函数模板) [编辑]
插入格式化数据
std::basic_ostream<CharT,Traits> 的公共成员函数) [编辑]
插入字符数据或插入到右值流中
(函数模板) [编辑]
序列化和反序列化复数
(函数模板) [编辑]
执行 bitset 的流输入和输出
(函数模板) [编辑]
对字符串执行流输入和输出
(函数模板) [编辑]
对伪随机数引擎执行流输入和输出
(函数模板) [编辑]
对伪随机数分布执行流输入和输出
(函数模板) [编辑]

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 614 C++98 整数除法的代数商是
在实现定义的方向上舍入
整数的代数商
除法向零截断
(小数部分被丢弃)
CWG 1450 C++98 a / b 的结果是未指定的,如果
它在结果类型中不可表示
a / b
a % b 在这种情况下的行为都是未定义的
CWG 1457 C++98 将正有符号值的最左边 1 位移入符号位的行为是未定义的
使其明确定义
明确定义
CWG 1504 C++98 数组元素的基础类子对象的指针
可以用于指针算术
在这种情况下,行为是
未定义的
CWG 1515 C++98 只有声明为 unsigned 的无符号整数
才应遵守模 2n 的算术定律
适用于所有无符号整数
CWG 1642 C++98 算术运算符允许其操作数为左值 某些操作数必须是右值
CWG 1865 C++98 CWG 问题 1504 的解决方案使涉及数组元素指针的指针算术的行为
涉及数组元素指针的指针算术的行为
如果指向类型和数组元素
类型在非顶层具有不同的 cv 限定符,则为未定义的
明确定义
CWG 1971 C++98 对于 ~ 的歧义规则是否适用于诸如 ~X(0) 之类的情况,尚不清楚
对于 ~ 的歧义规则是否适用于诸如 ~X(0) 之类的情况,尚不清楚
该规则适用于此类情况
CWG 2419 C++98 非数组对象的指针仅被视为
大小为 1 的数组的第一个元素的指针
在指针算术中,如果指针是通过 & 获得的
适用于所有指针
到非数组对象
CWG 2626 C++98 内置 operator~ 的结果仅仅是
“反码”,没有适当的定义
结果用
以 2 为基数的表示形式表示
CWG 2724 C++20 算术右移的舍入方向不明确 已明确
CWG 2853 C++98 对象末尾之后的指针可能
无法与整数相加或相减
它可以

[编辑] 参见

运算符优先级

运算符重载

常用运算符
赋值 递增
递减
算术 逻辑 比较 成员
访问
其他

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[...]
*a
&a
a->b
a.b
a->*b
a.*b

函数调用

a(...)
逗号

a, b
条件

a ? b : c
特殊运算符

static_cast 将一种类型转换为另一种相关类型
dynamic_cast 在继承层次结构中转换
const_cast 添加或移除 cv 限定符
reinterpret_cast 将类型转换为不相关的类型
C 风格转换 通过混合 static_castconst_castreinterpret_cast 将一种类型转换为另一种类型
new 创建具有动态存储持续时间的对象
delete 销毁先前由 new 表达式创建的对象并释放获得的内存区域
sizeof 查询类型的大小
sizeof... 查询 的大小 (自 C++11 起)
typeid 查询类型的类型信息
noexcept 检查表达式是否可以抛出异常 (自 C++11 起)
alignof 查询类型的对齐要求 (自 C++11 起)

C 文档 关于 算术运算符