您的位置:首页 > 编程语言 > C语言/C++

c++ primer 读书笔记八

2018-01-21 10:43 148 查看
2.4.4 constexpr和常量表达式

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

一个对象是不是常量表达式是由它的数据类型和初始值决定的

const int max_files=20;//max_files是常量表达式
const int limit=max_files+1;//limit是常量表达式
int staff_size=27;//staff_size不是常量
const int sz=get_size();//sz不是常量表达式


sz本身是一个常量,但它的具体值直到运行时才能获得,所以也不是常量表达式。

constexper变量

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

constexpr int mf =20;

constexpr int limit=mf+1;

指针和constexpr

必须明确一点,在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指的对象无关

const int *p=nullptr//p是一个指向整型常量的指针

constexpr int *q=nullptr//q是一个指向整数的常量指针

p和q类型相差甚远,p是一个指向常量的指针,而q是一个常数指针,其中的关键在constexpr把它定义为了顶层const

与其它常量指针类似,constexpr指针既可以指向常量也可以指一个非常量

constexpr int *np=nullptr;//np是一个指向整数的常量指针,值为空
int j=0;
constexpr int i=42;
//i和j都是定义在函数体之外
constexpr const int *p=&i;//p是常量指针,指向整型常量i
constexpr int *p1=&j;//p1是常量指针,指向整数


2.5类型别名

类型别名是一个名字,是某种类型的同义词

两种方法可用于定义类型别名。

typedef double wages;//wages是double的同义词

typedef wages base,p;//base是double的同义词,p是double的同义词

使用别名声明来定义类型的别名:

using SI=Sales_item//SI是sales_items的同义词

类型别名和类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名:

wages hourly,weekly;

SI item;//等价于Sales_item item

指针,常量和类型别名

如果某个类型别名指代的是复合类型或常量,那么吧它用到声明语句里就会就产生意想不到的后果。例如下面的声明语句用到了类型pstring,它实际是类型char*的别名

typedef char *pstring;

const pstring cstr=0;//cstr是指向char的常量指针

const pstring *ps;//ps是一个指针,它的对象是指向char的常量指针

此段学得不好,见书本

2.5.2auto类型说明符

c+11心标准引入auto类型说明符auto让编译器通过初始值来推算变量的类型。显然auto定义的变量必须有初始值:

auto item=val1+val2;item初始化为vall和val2相加的结果


使用auto也能在一条语句中声明多个变量,因为一条声明语句只能有一个基本数据类型,

使用auto也能在一条语句中声明多个变量。因为一条声明语句中只能有一个基本数据类型,所以该语句中所有变量的初始基本数据类型都必须一样:

auto i=0,*p=&i;//正确:i是整数,p是整型指针
auto sz=0,pi=3.14//错误:sz和pi的类型不一致


复合类型,常量和auto

编译器推断出来的auto类型有时候和初始值的类型并不完全一样,编译器会适当地改变结果类型使其更符合初始化规则。

使用引用其实是使用引用的对象,特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值。此时编译器以引用对象的类型作为auto的类型:

int i=0,&r=i;

auto a=r;//a是一个整数

其次,auto一般还会忽略顶层const,同时底层则会保留下来,比如当初始值指向常量的指针:

const int ci=i,&cr=ci;
auto b=ci;//b是一个整数(ci)
auto c=cr;/c是一个整数(cr是ci的别名,ci本身是一个顶层const)
auto d=&i;//d是一个整型指针(整数的地址就是指向整数的指针)
auto e=&ci;//e是一个指向整数常量的指针(对常量对象取地址是一种底层const)
如果希望推断出的auto类型是一个顶层const,需要明确指出:
const auto f=ci;
还可以将引用的类型设为auto,此时原来的初始化规则仍然适用:
auto &g=ci;//g是一个整型常量引用,绑定到ci
auto &h=42;//错误:不能为非常量引用绑定字面值
const auto &j=42;//正确:可以为常量引用绑定字面值


设置一个类型为auto的引用时,初始值中顶层常量属性任然保留。和往常一样,如果我们给初始值绑定引用和往常一样,如果我们给初始值绑定一个引用,则引用的常量就不是顶层常量了

当在一条语句中定义多个变量,切记,符号&和*只属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一个类型:

auto k=ci,&l=i;//k是整数,l是整数类型
auto &m=此,*p=&ci;//m是对整数常量的引用,p是指向整型常量的指针
auto &n=i,*p2=&ci;


2.5.3

decltype类型指示符

希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式,这个符号的作用是decltype,它的作用是选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值:

decltype(f())sum=x;//sum的泪洗就是符号f的返回类型
编译器并不实际调用函数f,而是使用当调用发生时f的返回值,编译器为sum指定的类型是什么呢?,就是假如f被调用的话将返回的那个类型。
decltype处理顶层const和引用的方式和auto有些不同,如果decltype使用的表达式是一个变量,则decltype返回该变量的类型

const
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: