国外免费搭建网站源码,深圳办公室装修哪家好,会议网站建设方案,东莞网站制作网络建设公司第四章 新手易学#xff0c;老兵易用
4.1 右尖括号的改进
在 C98 中#xff0c;有一条需要程序员规避的规则:如果在实例化模板的时候出现了连续的两个右尖括号 #xff0c;那么它们之间需要一个空格来进行分隔#xff0c;以避免发生编译时的错误。C98 会将老兵易用
4.1 右尖括号的改进
在 C98 中有一条需要程序员规避的规则:如果在实例化模板的时候出现了连续的两个右尖括号 那么它们之间需要一个空格来进行分隔以避免发生编译时的错误。C98 会将优先解析为右移。C11 中这种限制被取消了。事实上C11标准要求编译器智能地去判断在哪些情况下 不是右移符号。
4.2 auto类型推导
4.2.1 静态类型、动态类型与类型推导
在 C11 中标准委员会决定赋予 auto 全新的含义即auto 不再是一个存储类型指示符 ( storage-class-specifier如 static、extern、thread local等都是存储类型指示符 )而是作为一个新的类型指示符 ( type-specifier如 int、float 等都是类型指示符)来指示编译器auto 声明变量的类型必须由编译器在编译时期推导而得。auto声明的变量必须被初始化以使编译器能够从其初始化表达式中推导出其类型。
4.2.2 auto的优势
auto推导的优势1.在拥有初始化表达式的复杂类型变量声明时简化代码。2.免除在一些类型声明时的麻烦或者避免一些在类型声明时的错误。特别是在一些隐式或者用户自定义类型转换的情况。3.自适应性能够在一定程度上支持泛型的编程。这里举了一个例子 Max2因为可以保存运算结果提高了性能。而c98标准中因为无法获得a和b类型因此只能实现Max1宏。
4.2.3 auto的使用细则
首先c11中auto可以与指针和引用结合起来使用效果符合c/c程序员的想象。
其次auto与volatile和const之间也存在着一些相互的联系。声明为auto的变量并不能从其初始化表达式中带走cv限制符。
此外跟其他的变量指示符一样同一个赋值语句中auto可以用来声明多个变量的类型不过这些变量的类型必须相同。
4种不能推导的情况
1对于函数fun来说auto不能是其形参类型。
2对于结构体来说非静态成员变量的类型不能是auto的。
3声明auto数组。auto z[3]这样的数组会被编译器禁止。
4在实例化模板的时候使用auto作为模板参数。
为了避免和c98中auto的含义发生混淆c11只保留auto作为类型指示符的用法
4.3 decltype
4.3.1 typeid与decltype
c完全不支持动态类型c98部分支持动态类型也就是运行时类型识别RTTI。
RTTI机制为每个类型产生一个type_info类型的数据程序员可以在程序中使用typeid随时查询一个变量的类型typeid就会返回变量相应的type_info数据。而type_info的name成员函数可以返回类型的名字。而c11中又曾佳乐hash_code这个成员函数返回该类型唯一的哈希值以供程序员对变量的类型随时进行比较。
除了typeid外RTTI还包括c中的dynamic_cast等特性。
事实上在c的发展中类型推导是随着模板和泛型编程的广泛使用而引入的。
c 11对类型推导手段进行了细致的考量最终标准化为了auto以及decltype。
decltype的类型推导总是以一个普通的表达式为参数返回该表达式的类型。作为一个类型指示符decltype可以将获得的类型来定义另外一个变量。decltype类型推导也是在编译时进行的。
4.3.2 decltype的应用
c11中比较典型的就是decltype与typedef/using的合用。 decltype在某些场景下可以极大地增加代码的可读性。 在c中有时会遇到匿名类型使用decltype可以重用匿名类型。 有了decltype可以适当扩大模板泛型的能力。 decltype在标准库中也有一些应用例如基于decltype的模板类result_of其作用是推导函数的返回类型。
4.3.3 decltype推导四规则
1.如果e是一个没有带括号的标记符表达式或类成员访问表达式那么decltype(e)就是e所命名的实体的类型。此外如果e是一个被重载的函数则会导致编译时错误。
2.否则假设e的类型是T如果e是一个将亡值xvalue那么decltype(e)为T。
3.否则假设e的类型是T如果e是一个左值则decltype(e)为T。
4.否则假设e的类型是T则decltype(e)为T。
标记符表达式 (id-expression )基本上所有除去关键字、字面量等编译器需要使用的标记之外的程序员自定义的标记 (token ) 都可以是标记符 (identifier )。而单个标记符对应的表达式就是标记符表达式。 4.3.4 cv限制符的继承与冗余的符号
与auto类型推导时不能带走cv限制符不同decltype能够带走表达式的cv限制符。不过如果对象的定义中有const或volatile限制符使用decltype进行推导时其成员不会继承const或volatile限制符。
与auto相同decltype从表达式推导出类型后进行类型定义时也会允许一些冗余的符号。比如cv限制符及引用符号通常如果推导出的类型已经有了这些属性冗余的符号则会被忽略。 4.4 追踪返回类型
4.4.1 追踪返回类型的引入
c98中如果一个函数模板的返回类型依赖于实际的入口参数类型那么该返回类型在模板实例化之前可能都无法确定这样的话在定义函数模板时就会遇到麻烦。
最直观的解决方式时对返回类型进行类型推导。 编译器在推导decltype(t1t2)时表达式t1和t2都未声明为了解决这个问题c11引入新语法--追踪返回类型来声明和定义这样的函数。 auto占位符和-return_type构成追踪返回类型函数的两个基本元素。 4.4.2 使用追踪返回类型的函数
4.5 基于范围的for循环
对于一个有范围的集合说明循环的范围是多余的。可以使用基于范围的for循环来遍历 如果不需要修改迭代变量的值也可以不使用引用 使用auto可以更简练 使用for循环迭代要求范围是确定的数组大小不能确定是不能使用基于范围的for循环例如 例子里作为参数传过来的数组a的范围不能确定。
基于范围的循环使用标准库容器时如果使用auto来声明迭代的对象时这个对象不是迭代器对象而是解引用后的对象。