3、const与constexpr
初遇到constexpr真的是有点懵比,看了很多博客也没看懂,不知道是我太笨,还是别人写的太深奥?总之经过一番折腾算是入门了。一下是我个人总结,有不对的地方望指出。
一、学习const与constexpr必须要先知道一下几个概念:
1、constexpr是constant expression的缩写。顾名思义“常量 表达式”
2、何为常量表达式(constant expression):是指由编译器求值的表达式。
在这里在解释一下编译器求值概念:编译系统由预处理器、编译器、汇编器、连接器四部分组成
一个源文件到一个可执行文件要经过这四部分,所谓的编译器求值指的就是第二部分编译器部分,
二、 C++中的const与constexpr都是与“常量”有关的两个概念。
1、C++中的const兼容了C语言中的const。
(1)C语言中的const:
① 编译器可以把声明带 const 限定类型的对象放到只读内存中。
② const
语义仅应用到左值表达式
③ 指代 const 限定类型对象的左值表达式,和指代拥有至少一个 const 限定类型成员(包含为聚合体或联合体所递归含有的成员)的结构体或联合体的左值表达式,不是可修改左值。具体而言,它们不可赋值:
const 限定的结构体或联合体类型的成员,取得它所属类型的限定版本(在用 .
运算符或 ->
运算符访问时)。
若以 const 类型限定符声明数组类型(通过使用 typedef ),则数组类型无 const 限定,但其元素类型有。若以 const 类型限定符声明函数类型(通过使用 typedef ),则行为未定义。
指向非 const 类型的指针能隐式转换成指向同一或兼容类型的 const 限定版本的指针。能用转型表达式进行逆向转换。
注意指向指向 T
指针的指针不可转换为指向指向 const T
指针的指针;对于要兼容的二个类型,其限定必须等同。
2、constexpre的用法:
constexpr
- 指定变量或函数的值可在常量表达式中出现-
解释
constexpr
说明符声明可以在编译时求得函数或变量的值。然后这些变量和函数(若给定了合适的函数实参)即可用于仅允许编译时常量表达式之处。用于对象或非静态成员函数 (C++14 前)声明的 constexpr 说明符蕴含 const。用于函数声明的 constexpr说明符或 static 成员变量 (C++17 起)蕴含 inline。若函数或函数模板的任何声明拥有constexpr
说明符,则每个声明必须都含有该说明符。 -
constexpr 变量必须满足下列要求:
- 其类型必须是字面类型 (LiteralType) 。
- 它必须被立即初始化
- 其初始化的全表达式,包括所有隐式转换、构造函数调用等,都必须是常量表达式
constexpr 函数必须满足下列要求:
|
(C++20 前) |
|
(C++14 前) | ||
(=default; 或 =delete; 的函数体不含任何上述内容。) |
(C++14 起) |
-
- 它必须非虚
(C++20 前) - 它必须不是协程
(C++20 起) - 其返回类型(若存在)必须是字面类型 (LiteralType)
- 其每个参数都必须是字面类型 (LiteralType)
- 对于构造函数与析构函数 (C++20 起),该类必须无虚基类
- 至少存在一组实参值,使得函数的一个调用为核心常量表达式的被求值的子表达式(对于构造函数为足以用于常量初始化器)(C++14 起)。不要求对这点的诊断。