const 和const expr:
相比于c++的老标准,c++11新标准引入const expr这个类型,下面简要说一下,这两个不同的类型的相同点和不同点:
1:用const 和const expr声明的变量它们的值一旦被定义后就不能被改变。如下面例子代码所示:
const int x1=0; //okay;
x1=1; //error, the value of variable x1 can't be changed;
constexpr int x2=10; //okay;
x2=11; //error, the value of variable x2 can't be changed.
2:当给const 变量赋值的时候,我们不仅能用常量表达式(在编译的时候结果就已经知道的表达式)赋值,还能用非常量表达式赋值;但是当我们给constexpr变量赋值的时候,我们只能用常量表达式赋值,不能用非常量表达式赋值。如下面代码例子所示:
//假定函数sqrt()不是常量表达式!
const int x1=0; //okay, 0是整型常量,为常量表达式;
const int x2=sqrt(9); //okay, sqrt(9)不是常量表达式,但可以对const 对象赋值;
constexpr int x3= 0; //okay, 0是常量表达式;
constexpr int x4=sqrt(9); //error! sqrt(9)不是常量表达式,不可以对constexpr对象赋值;
事实上,当声明为const时,我们只是承诺不去改变这个值,但不关心它是否在编译时被计算出来还是在程序运行时计算出来;但当声明为constexpr 时,我们要求值一定要在编译时计算出来,假如我们定义了constexpr int x4=sqrt(9)
,因为sqrt(9)不是常量表达式,因此x4的值不能在编译时就能得到,所以上述定义就是错误的。
3:因此constexpr有另外一个功能,就是能够用于声明一个函数为常量表达式,也就是说这个函数的结果可以在编译时计算出来。如下面例子所示:
constexpr double square(double x){ return x*x;}
用constexpr来声明square()函数,就意味着square()函数是常量表达式,它的值可以在编译时计算出来。并且由于square()是常量表达式,因此我们可以用它来给constexpr类型的变量赋值,如下面代码所示:
constexpr double val=square(8); //okay! square(8)是常量表达式。