1、与const不同,constexpr的初始值必须时常量表达式(值不会改变,并且在编译阶段就能知道计算结果的表达式);
constexpr int a = 1;
constexpr int b = a+1;
constexpr int c = fun(); //fun()可能不是常量表达式
2、因为常量表达式的值在编译阶段就必须知道,所以声明constexpr用到的类型为字面值类型(算术类型、指针、引用等),自定义类、IO库等非字面值类型不能用constexpr;
class AA;
constexpr AA a; //错误 AA 不是字面值类型
3、constexpr定义指针或引用变量时,初始值必须有固定地址(全局和静态变量就有固定地址),指针的初始值也可以为nullptr;
int a = 1; //局部
int g_a; //全局
static int s_a;
constexpr int &y1 = g_a, &y2 = s_a;
constexpr int *p1 = &g_a, * p2 = &s_a, * p3 = nullptr;
constexpr int &y = a, * p = &a; // 错误,a没有固定地址
4、用constexpr定义的指针属于顶层const,而不是底层const,注意和const定义的指针区分;
int g_a = 1;//全局
const int * p1 = &g_a; //底层const,不能改变怕p1所指对象的值,但可以改变p1所指对象
constexpr int * p2 = &g_a; 顶层const,与p1相反
constexpr const int * p3 = &g_a; 既是顶层const,也是底层const