c++11特性之constexpr

更多c++后台开发知识点,请参考我的博客:https://blog.csdn.net/ypshowm

常量表达式是指值不会改变且在编译过程就能得到计算结果的表达式。显然,字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。

在一个复杂的系统中,很难分辨一个初始值到底是不是常量表达式,因此

c++11规定:允许将变量声明为constexpr类型,以由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

constexpr int mf = 20;    //20是常量表达式
constexpr int limit = mf + 1;    //mf+1是常量表达式
cosntexpr int sz = size();    //只有当size是一个constexpr函数时,这条语句才正确

由于常量表达式的值需要在编译时就得到计算,因此声明constexpr时用到的类型必须有所限制。

算术类型,引用和指针属于字面值类型,自定义的类如IO库,string类型等不属于字面值类型,不能被定义成constexpr;

对引用和指针的限制:一个constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址中的对象

函数体内定义的变量一般来说是并非存放在固定地址中,因此constexpr指针不能指向这样的变量。相反,所有函数体之外的对象其地址固定不变,能用来初始化constexpr指针。

在constexpr声明中,如果定义了一个指针,限定符constexpr只对指针有效。与指针所指对象无关:

const int *p = nullptr;    //p是一个指向整型常量的指针(注意这里是指向nullptr,)
int a = 42;
const int *p = &a;    //p是一个指向整数的常量指针
constexpr int *q = nullptr;    //q是一个指向整数的常量指针;

 constexpr函数

constexpr函数是指能用于常量表达式的函数,有几条与其他函数不一样的规定:函数的返回类型以及所有的形参的类型都是  字面值类型,而且函数体中必须只有一条return语句(当然也可以包含其他语句,不过这些语句在运行时不能执行任何操作),、

constexpr int new_sz() {return 42;}
cosntexpr int foo = new_sz();    //正确,foo是一个常量表达式

执行该初始化任务时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式的指定为内联函数(inline); 

constexpr的好处:

  1. 是一种很强的约束,更好地保证程序的正确语义不被破坏。
  2. 编译器可以在编译期对constexpr的代码进行非常大的优化,比如将用到的constexpr表达式都直接替换成最终结果等。
  3. 相比宏来说,没有额外的开销,但更安全可靠。

猜你喜欢

转载自blog.csdn.net/ypshowm/article/details/89137563