一、常量表达式和 constexpr
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式,字面值属于常量表达式。一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定。
const int max_files =20 ;//max_files是常量表达式
const int limit = max_files +1; //limit是常量表达式
int staff_size =27;//数据类型是个普通的int,staff_size并非常量表达式
const int sz = get_size();//尽管sz本身是一个常量,但是具体值要到运行时才能得到,所以sz不是常量表达式
利用constexpr声明变量,可以帮助我们检验变量是否为一个常量表达式
constexpr int mf = 20;//正确
constexpr int limit = mf +1;//正确
constexpr sz = size();//只有当size是一个constexpr函数时,才是一条正确的声明
(constexpr函数足够简单使得编译时就可以计算其结果)
只有字面值类型(算术类型、引用、指针)才能定义成constexpr,自定义类Sales_item、IO库、string类型不属于字面值类型,则不能定义成constexpr。
constexpr指针指向的变量一般只能定义在函数体外,即只能指向存放在固定地址中的变量。
二、类型别名
有两种方式定义类型别名:typedef unsigned int uint;
using sb = unsigned int;
如果某个类型别名指代的是复合类型或常量,那么把它用在声明语句里,就很容易出错。typedef char* pstring;
const pstring cstr =0;//cstr是一个常量指针,它指向char变量
const pstring ps;//ps 是一个常量指针,它指向char变量的指针
即当类型别名指代的是复合类型时,就不是简单的替换理解了,const形容的是整个别名。
三、auto、decltype
auto来定义变量,用它能让编译器替我们去分析表达式所属的类型,但必须赋初值,当用auto同时定义两个变量时,这两个变量的类型需要一致。
//auto一般会忽略掉顶层const:int i =0;
const int ci =i , &cr=ci; auto b =ci ;//b为一个整数(ci的顶层const被忽略了) auto c =cr ;//c为一个整数 auto d =&i;//d为一个整形指针 auto e =&ci;//e为一个指向整形常量的指针(对常量对象取地址是一种底层const)
//如果希望推断出来的auto类型是一个顶层const,需要明确指出 //如:const auto f =ci;
decltype() 可用来根据选择并返回操作数的数据类型,相当于一个数据类型(decltype不会忽略顶层const)
如: const int ci =0, &cj = ci;
decltype(ci) x =0//x的类型是const int
decltype(cj) y =x//y的类型是const int &,将y绑定到变量x
引用从来都是是作为所指对象的同义词出现,但是在decltype这里是个例外,即decltype(var)时,只要var是引用,得到的就是引用
decltype(*p) int i =42, *p = &I,&r=I;
。
decltype(r+0) b;//b是一个int变量
decltype(*p) c;//错误,这样的话 decltype(*p)相当于int &,定义引用要赋初始值
如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量类型;如果给变量加上了一层或多层括号,就会得到一个引用类型
decltype((i)) d;错误,d是一个int&,必须初始化。
decltype(i) e;正确,e是一个int
赋值会产生引用的一类型表达式,引用的类型就是左值的类型
int a = 3, b = 4;
decltype (a) c = a;
decltype (a = b) d = a;//则d是一个int&类型。
个人理解:
由decltype指定类型和由auto指定类型的区别
利用decltype和auto都可以很方便的定义一个变量,decltype是以类似于函数的形式取某个表达式或者变量的数据类型,将他用于定义新变量,auto是根据这个新变量的初始化时赋的值或者表达式来决定这个新变量的数据类型。但decltype(var)里,只要var是一个引用,则可以直接定义一个引用,而auto就算赋一个引用,也只会赋一个被它引用的对象的数据类型,要是真想定义一个引用需要自己手动在auto后面加&。