表达式

来自cppreference.com
< cpp‎ | language
 
 
 
表达式
概述
值类别(左值 lvalue 、右值 rvalue 、亡值 xvalue )
求值顺序(序列点)
常量表达式
不求值表达式
初等表达式
lambda 表达式(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)
用户定义转换
 

表达式是运算符和它们的运算数的序列,它指定一项计算。

表达式的求值可以产生一个结果(比如 2+2 的求值产生结果 4 ),也可能产生副作用(比如对 std::printf("%d",4) 的求值在标准输出上打印字符 '4' )。

目录

[编辑] 概述

  • 值类别(左值 (lvalue) 、右值 (rvalue) 、泛左值 (glvalue) 、纯右值 (prvalue) 、亡值 (xvalue) )是根据表达式的值所进行的分类
  • 实参和子表达式的求值顺序指定获得中间结果所用的顺序

[编辑] 运算符

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

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_cast 添加或移除 cv 限定符
reinterpret_cast 转换类型到无关类型
C 风格转型static_castconst_castreinterpret_cast 的混合转换一个类型到另一类型
new 创建有动态存储期的对象
delete 销毁先前由 new 表达式创建的对象,并释放其所拥有的内存区域
sizeof 查询类型的大小
sizeof... 查询形参包的大小(C++11 起)
typeid 查询类型的类型信息
noexcept 查询表达式是否能抛出异常(C++11 起)
alignof 查询类型的对齐要求(C++11 起)

[编辑] 转换

[编辑] 内存分配

[编辑] 其他


[编辑] 初等表达式

任何运算符的操作数都可以是其他的表达式或者是初等表达式(例如,1+2*3 中 operator+ 的操作数是子表达式 2*3 和初等表达式 1)。

初等表达式包括以下各项:

1) 字面量(例如 2"Hello, world"
2) 经过适当声明的无限定的标识符(例如 ncout
3) 经过适当声明的有限定的标识符(例如 std::string::npos
4) Lambda 表达式 (C++11)
5) 折叠表达式 (C++17)

括号中的任何表达式也被归类为初等表达式:这确保了括号具有比其他运算符更高的优先级。括号保持值、类型和值类别不变。

[编辑] 字面量

字面量是 C++ 程序中用以表现嵌入到源代码中的常量值的记号。

  • 整数字面量是整数类型的十进制、八进制、十六进制或二进制的数值
  • 字符字面量charchar16_tchar32_twchar_t 类型的单个字符
  • 浮点字面量floatdoublelong double 类型的值
  • 字符串字面量const char[]const char16_t[]const char32_t[]const wchar_t[] 类型的字符序列
  • 布尔字面量bool 类型的值,即 truefalse
  • nullptr 是指针字面量,指定一个空指针值 (C++11 起)
  • 用户定义字面量是用户指定的类型的常量值 (C++11 起)

[编辑] 不求值表达式

运算符 typeidsizeof noexceptdecltype (C++11 起) 的运算数是不求值表达式(除非运算符为 typeid 而运算数是多态泛左值),因为这些运算符仅查询其运算数的编译期属性。因此,std::size_t n = sizeof(std::cout << 42); 不进行控制台输出。

不求值的运算数被当做完整表达式,即便它们在语法上是某个更大的表达式的操作数(例如,这意味着 sizeof(T()) 要求 T::~T 可访问)

(C++14 起)

requires 表达式也是不求值表达式。

(C++20 起)

[编辑] 弃值表达式

弃值表达式是仅用来实施其副作用的表达式。从这种表达式所计算的值被丢弃。这样的表达式包括任何表达式语句的全表达式,逗号运算符的左边的实参,以及转换为类型 void 的类型转换表达式的实参。

对弃值表达式所计算的结果不会进行数组向指针和函数向指针的转换。不过要进行左值向右值转换,但只会在该表达式是 volatile 限定的泛左值,并且具有以下形式之一(可能带有括号)时才会进行:

  • 标识表达式(id-expression)
  • 数组下标表达式
  • 类成员访问表达式
  • 间接
  • 成员指针操作
  • 条件表达式,其第二个和第三个操作数都是这些表达式中的一种
  • 逗号表达式,其右操作数是这些表达式中的一种。

此外,若表达式具有类类型,则要求用 volatile 复制构造函数初始化作为结果的右值临时对象。

(C++17 前)

如果表达式(经过可能会发生的任何左值向右值转换之后)是纯右值,则进行临时对象的实质化。当原泛左值是 volatile 限定的类类型时,需要一个 volatile 复制构造函数来初始化其结果右值临时对象。

在表达式丢弃声明为 [[nodiscard]] 的值,且非转型为 void 时,编译器可以发布警告。

(C++17 起)