constexpr 和 const
1. 常量表达式
constexpr = const expression
1.1 什么是常量表达式
常量表达式是 值不会变 且在 编译期就能得到结果 的表达式。
1.2 const 的缺陷
const
无法确保修饰的变量在编译期就能得到结果。
int i1 = 42;
const int i2 = i1; // i1 不是常量表达式,因此 i2 也不是常量表达式
const int i3 = 42; // i3 是常量表达式
const int i4 = i3 + 1; // i3 + 1 是常量表达式,因此 i4 也是常量表达式
const int i5 = get_size(); // 如果get_size() 不是常量表达式,则 i5 不是常量表达式
因此,无法直接判断 const
修饰的对象是否是常量表达式,需要使用 constexpr
来明确指出。
1.3 constexpr 的优点
- constexpr 修饰的变量在编译期就能得到结果。
- 只有
constexpr
的所有实参都是常量表达式时,constexpr函数才是常量表达式。 - 只要有一个实参不是常量表达式,constexpr函数就不是常量表达式,那就和普通函数没什么区别了,在运行时计算
constexpr int sum(int a, int b)
{
return a + b;
}
constexpr int i1 = 42;
constexpr int i2 = sum(i1, 2); // 所有参数都是常量表达式,sum的结果也是常量表达式,在编译期求职
int AddTree(int i)
{
return sum(i, 3); // 不是常量表达式,此时sum作为普通函数使用
}
1.4 constexpr 的限制
- 返回类型和所有形参类型都是 字面值类型。除了内置类型,用户定义的类型也可以是字面值类型,因为它的构造函数和成员函数也可以是
constexpr
的。 - 返回值不是能void类型。
- 函数体中有且只有一条return语句,但可以用
?:
三目运算符和递归 - 如果是类的成员函数,则为隐式 const 成员函数
1.5 小结
- const 只能保证 修饰的变量不被修改,不能保证 在编译期就能得到结果。
- constexpr 修饰的变量在编译期就能得到结果,也可以 作为普通函数使用