constexpr和const的区别

这样想:

C++的const关键字一直以来都有双重语义问题,也就是变量的“Readonly”和“No Change”两个语义

C++11为了解决这个问题,提出了constexpr关键字,让它来强调“No Change”这个语义

const只强调“只读”语义。

在const中,“只读”不就意味着其不能被修改吗?答案是否定的,“只读”和“不允许被修改”之间并没有必然的联系

1
2
3
4
5
int x = 42;
const int & con_x = x;
cout << con_x << endl; // 输出42
x = 43;
cout << con_x << endl; //输出43

在这个例子中,con_x是const修饰的“只读”引用变量,但是这并不代表con_x的“值”不会被改变,只是表示不可以通过con_x去修改,con_x是“ReadOnly”而已,无法通过变量自身去修改自己的值。但这并不意味着 con_x 的值不能借助其它变量间接改变,通过改变 x 的值就可以使 con_x 的值发生变化。

而使用constexpr就不一样了,constexpr不但强调了“只读”,同时强调了“常量”这一点,也就是它的值永远不会改变。

例:可以使用constexpr修饰的int“变量”(其实已经是常量了)来初始化数组,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
constexpr int sqr1(int arg)
{
return arg*arg;
}

const int sqr2(int arg)
{
return arg*arg;
}

int main()
{
array<int,sqr1(10)> mylist1; //可以,因为sqr1时constexpr函数
array<int,sqr2(10)> mylist1; //不可以,因为sqr2不是constexpr函数
return 0;
}

其中,因为 sqr2() 函数的返回值仅有 const 修饰,而没有用更明确的 constexpr 修饰,导致其无法用于初始化 array 容器(只有常量才能初始化 array 容器),并且编译器其实会在编译阶段就计算数组的大小