| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> Item 6: Use the explicitly typed initializer idiom when auto deduces undesired types. -> 正文阅读 |
|
[数据结构与算法]Item 6: Use the explicitly typed initializer idiom when auto deduces undesired types. |
Item 6: Use the explicitly typed initializer idiom when auto deduces undesired types.这次是对 Effective Modern C++ Item 6 的学习笔记。 在 Item 5 中介绍了使用 auto 申明类型的优势,也在 Item 2 介绍了 auto 类型推导的方式和 auto 类型推导有时候并非如我们所愿的情况,本文继续分析使用 auto 存在的问题。 看下面的例子,函数 features 入参为 Widget 类型,返回一个 std::vector<bool>,每一个 bool 代表 Widget 是否提供一个特殊的特性:
假设 bit 5 代表是否有高优先级,可能编码如下:
如果修改 highPriority 显示申明为 auto :
将导致 processWidget 出现不可预测的行为,这是为什么呢?对 vector <T> 的 operator [] 操作,一般我们期望得到 T& 类型。但是对于 vector <bool> 的 operator [] 操作,得到的是 std::vector<bool>::reference 类型,却不是 bool& 类型。 为什么会有std::vector<bool>::reference 类型呢?主要是以下几个原因:
由于以上几点,再看下这段代码:
这里,features 返回的是 std::vector<bool> 对象,然后施加 operator [] 操作得到 std::vector<bool>::reference 对象, 最后被隐式转化为 bool 类型来初始化 highPriority,highPriority 得到 std::vector<bool> 中 bit 5 的值。
将 bool 换成 auto,由于 auto 的自动类型推导,最后无法得到 std::vector<bool> 中 bit 5 的值。具体是什么值取决于 std::vector<bool>::reference 的实现。std::vector<bool>::reference 的一种实现是这样的:这个对象包含一个指针,这个指针指向一个 word(word 存储了引用的 bit ,加上 word 中 bit 的 offset。在这里,features 返回的是一个 std::vector<bool> 临时对象 temp,operator [] 操作后,得到 std::vector<bool>::reference ,它包含一个指向 temp 中 word 的指针,加上 bit 5 的偏移。因此,在语句结尾,临时的 temp 被销毁,highPriority 包含了一个野指针,这将导致 随后的 processWidget 函数的不可预测的行为。 这里可以使用显示类型初始化方式使用 auto :
std::vector<bool>::reference 是代理类(proxy class)的一个例子,代理类的目的是为了模拟和扩展某些其他类型行为,具有广泛的使用,比如标准库的智能指针类型。 在表达式模板中也使用代理类的技术,能够提高数值计算的效率。比如给定一个类 Matrix 和 Matrix 的对象 m1, m2, m3 和 m4,以下表达式:
operator + 返回一个代理类对象将更加高效。operator + 两个 Matrix 对象得到代理 Sum<Matrix, Matrix> 对象,而不是Matrix 对象,上面的表达式将得到 Sum<Sum<Sum<Matrix, Matrix>,Matrix>, Matrix> 对象,最后隐式转化为为 Matrix 对象。 这种隐形的代理类遇到 auto 时候往往得不到预期的结果。因此,一般防止出现以下语句:
一种方式是使用显式的类型申明,一种方式是使用 static_cast 显示类型初始化:
这样的习惯不仅用于代理类的情况,在定义一个变量的类型及其初始化表达式类型不同时,也最好显式申明变量类型,或者显示类型初始化。例如:
最后,总结一下:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 18:38:55- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |