常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。
字面值和用常量表达式初始化的const对象也是常量表达式。
const int mar_files = 20; //常量表达式
const int limit = mar_files +1 ; //常量表达式
int staff_size = 27 ; //这是一个普通的Int型数据,不是常量表达式
const int sz = get_size(); //这不是一个常量表达式,因这sz的值要到具体运行时才能够得到,而常量表达式的值是要在编译过程中就能得到,所以它不是一个常量表达式
constxpr变量:
C++11新标准:允许将变量声明为constexpr类型方便编译器来验证变量的值是否是一个常量表达式。
当我们把变量声明为constexpr的时候,它一定是一个常量,而且必须用常量表达式初始化它。
constexpr int mf = 20 ; //20是一个常量表达式
constexpr int limit = mf+1 ; //mf +1是一个常量表达式
constexpr int sz = size(); //只有当size函数是一个constexpr函数的时候才是正确声明语句。
在新标准下允许定义一种特殊的constexpr函数,这种函数不能太过于复杂,应该足够简单,在编译时就能得到计算结果,就可以用constexpr去初始化constexpr变量了。
#include "iostream"
using namespace std;
constexpr int SUM();//声明constexpr函数
int main() {
constexpr int num = 0;
int num1 = SUM();
constexpr int num2 = SUM();//正确的,因为SUM()是一个constexpr函数,并且它也足够简单
}
constexpr int SUM() {//定义constexpr函数
return 2;
}
建议:如果你认定变量是一个常量表达式,就把它声明成constexpr类型。
字面值类型:
一般比较简,值也显而易见、容易得到的类型就可以称为是字面值类型。
算术类型,引用和指针都属于字面值类型。IO库、string类型则不属于字面值类型,也不能被宝岛成constexpr。
尽管指针的和引用都能被定义成constexpr,但它们的初始值却受到严格限制。一个constexpr指针的初始值必须是nullptr或者0,或者是存储某个固定地址中的对象。
如果在constexpr声明中定义了一个指针,限定符constexpr仅对指针有效,和它所指的对象无关。
const int *p = nullptr; //P是一个指向整形常量的指针
constexpr int *q = nullprt; //q是一个指向整数的常量指针
constexpr把它所定义的对象置为了顶层const。和其他常量指针相同,constexpr指针既可以指向常量也可以指向一个非常量。
给一个练习题大家做一做:
//下面的语句是否合法,若不合法请修改:
int null=0 , *p = null;