constexpr变量、constexpr函数和常量表达式

常量表达式: 值不会改变且在编译过程中就可得到结果

const int max = 20;//max是常量表达式
const int min = max-19;//min是常量表达式

constexpr用途:便于编译器验证变量是否为常量表达式

constexpr int max =20;//20是常量表达式
constexpr int min = max-19;//max-19是常量表达式
constexpr int sz =size();//仅仅当size()是一个costexpr函数时正确

constexpr函数:

返回值类型及形参类型必须是字面量类型,且必须有且只有一个return语句

constexpr int fun()//constexpr函数,编译时验证返回值是constexpr
{
    return 42;
}
constexpr int result = fun();//正确,把fun是一个常量表达式
  • constexpr函数体内部不能有其他语句,只能有类型别名,using声明。只不过在运行时,不执行任何操作。

  • constexpr函数可以返回非常量

    constexpr scale(int i){return 100*i;}
    
    int arr[scale(2)];//正确,scale(2)是常量表达式
    int j =100;
    int a2[sacle(j)];//错误,scale(j)不是常量表达式
    

    如上例,当传入字面值2时,返回类型也是常量表达式,此时,编译器直接替换。但是使用非常量表达式,则返回值是一个非常量表达式,此时将其赋值给需要常量表达式的上下文中,编译器报错。

  • 因为constexpr函数在编译阶段就已经替换,此时如果只将声明放入头文件中而没有定义是不够的,所以一般将内联函数和constexpr函数放到头文件中。

指针和constexpr

const int *p = nullptr;
constexpr int *q = nullptr;//等同于 int* const q;

int j =0;
constexpr int i = 100;
constexpr const int*p =&i;//i不能是函数体之内 必须加上const
constexpr int* p =&j;

指针和引用都可以定义成constexpr,但是初始值受到限制,必须是nullptr或者0,或者是固定地址的对象

注意: 1. 函数体内的局部变量没有固定地址,所以constexpr指针不能指向他们

​ 2. 函数体内的静态变量具有固定地址,是可以使得constexpr绑定