常量表达式
常量表达式指由字面量、常量、函数、运算符组成的表达式,值是一个固定值
编译器在编译时就会将它用结果值替换,而不需要运行时再去计算
constexpr
使用constexpr修饰函数返回值、变量等,编译器可以在编译阶段计算其值,以便用于数组、模板非类型参数、枚举等
也可以提高程序运行效率
constexpr修饰变量
constexpr int a{10};
这里变量必须初始化,初始值必须是一个常量表达式
constexpr修饰函数
这种函数被称为常量表达式函数
若所有实参都是常量表达式,则该调用也是常量表达式
1
2
3
4
5
6
7
constexpr int mul(int a,int b){
return a*b;
}
constexpr int c = mul(5,3); //常
int d = mul(c,11); // 常
int f = mul(d, 7); // 变要求:
- 返回值和传参都是字面类型
- 函数中不能调用非constexpr函数(
<iostream>库,<thread>库都不可以用) - 不能抛出异常
- 对于递归,编译器有递归深度的限制,用参数
-fconstexpr-depth控制,默认512
constexpr修饰自定义类型
若想定义自己的constexpr类,可以将类的构造函数定义为常量表达式函数
1
2
3
4
5
6
7
8
9
10
11
class complex{
public:
constexpr complex(double r = 0, double i = 0):_r(r),_i(i){}
constexpr double getreal() const{return _r;}
constexpr double getimg() const{return _i;}
constexpr void setreal(double v){_r = v;}
constexpr void setimg(double v){_i=v;}
private:
double _r;
double _i;
}const与constexpr
const与constexpr的效果相同,整型下可以混用
如这是合法的
1
2
const int a = 12;
constexpr int b = a+3;这是非法的,需要统一使用constexpr
1
2
const float a = 12;
constexpr float b = a+3;因为const包含运行时的只读变量(多数情况)或编译时的常量(少数情况)
而constexpr指的是编译时的常量