Last Updated on 2022年9月28日
Const Expression, constexpr 是一个非常复杂的话题, 幸运的是, 我们在实践中
需要记住的内容并不太多,因为常见的应用场景其实比较简单.
const
限定符
const
是一种编译期特性,用于限定对象的编译期写入权限, 编译器也可能将const对象视作constexpr进行优化.- 理论上可以通过各种
trick
在运行期写入对象,但是不要这么做. - 当项目很大,或者开发人员很多时,使用
const
就能利用编译器约束开发人员的行为,给开发人员做一定提醒.
- 理论上可以通过各种
- 原则上,当我们创建一个变量时,若认为它不应当被修改,就应当声明称
const
型.最常用的场合是函数形参/返回值中的const T &
. const
限定的全局对象默认是static
的,不会跨文件共享,正因此,若const对象可能被共享,也应当优先定义在头文件中.const
在与指针联用时,要注意限定的部分.规定:若限定指针自身为不可写,则将const
写在*
右侧;若是指向的对象不可写,则const
写在*
左侧.- 若
const
用于限定对象自身不可写,那么该对象必须初始化. - 对于自定义类,也可以限定
this
指向const T
constexpr
限定符(C++11)
constexpr
是一种编译期特性.它用于限定表达式的结果必须是编译期常量.- 编译期常量粗略可以按值分为两类:
- Concrete: 字面意思, 表示可以在编译期计算出一个整数值.
- Opaque: 只有常量的意义,但是在编译期没有具体的值,例如静态区对象的地址. 例如,
constexpr int * p=&a;
,只要a
是静态区的对象,那么这个语法就是正确的.
constexpr
可以用于限定函数,功能是:若该函数的输入为字面值常量,那么该函数必须可以在编译期求值.- constexpr函数在形式上也有较为严格的限制
- 构造函数也可以是constexpr的,只要它足够简单.
- constexpr函数默认是inline的.
- 当一个类满足一些(很苛刻的)条件时,类对象也可以作为字面值常量.
- 使用constexpr不但有利于编译器优化(编译期替换),还可以切实的产生运行期的对象,从而保证运行期可以作为const对象传入,这是define所不能做到的.
- constexpr的bool值在编程中是非常有用的,它可以配合SFINAE,if-constexpr,Concept形成很灵活的编译期功能.
- constexpr的int值也常用在模板编程中,它可以辅助我们进行一些编译期计算.