1、字面值常量:一个形如42的值被称作字面值常量,这样的值一望而知。每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型,包含:
- 整型和浮点型字面值
- 字符和字符串字面值
- 布尔字面值和指针字面值:
bool test = false;
nullptr是指针字面值;
2、常量表达式:指值不会改变并且在编译过程就能得到计算结果的表达式。很显然,字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。一个对象是不是常量表达式由它的数据类型和初始值共同决定。例如
const int max_files = 20; //常量表达式 const int limit = max_files + 1 ; //limit是常量表达式 int staff_size =27;//staff_size不是常量表达式 const int sz = get_size();//sz不是常量表达式,因为在编译期间不能得到sz的值,只有在运行时才能得到;
3、constexpr变量
C++语言有几种情况是要用到常量表达式的。我们当然可以定义一个const变量并且把一个初始值设为我们认为的某个常量表达式,但是,在一个复杂的系统中,很难(几乎不可能)分辨一个初始值到底是不是常量表达式。那么在实际的使用中,尽管我们本意是把一个const变量的初始值设为一个常量表达式,但是在实际的运行中我们发现却并不是表达式的情况。在此种情况下,对象的定义和使用根本就是两回事。
so,C++11规定,允许将变量声明为constexpr类型,以便由编译器来验证变量的值是不是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
constexpr int mf = 20;//20是常量表达式; constexpr int limit = mf + 1;//mf+1是常量表达式; constexpr int sz = size() //只有当size()是一个constexpr函数时,才是一条正确的声明语句;
4、字面值类型:常量表达式的值需要在编译时就得到计算,因此对声明constexpr时用到的类型必须有所限制。这些类型统称为字面值类型(literal type)。
- 算数类型、引用、指针是字面值类型
constexpr int a = 0;//算数类型int是字面值类型; - 某些类也是字面值类型,这些类叫做字面值常量类假设类Debug是字面值常量类。那么:
constexpr Debug debug(args);//生成一个constexpr对象-debug;
参考:
C++ primer P59、P267