IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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 是否提供一个特殊的特性:

std::vector<bool> features(const Widget& w);

假设 bit 5 代表是否有高优先级,可能编码如下:

Widget w;bool highPriority = features(w)[5];  // is w high priority?processWidget(w, highPriority);     // process w in accord
                                    // with its priority

如果修改 highPriority 显示申明为 auto

auto highPriority = features(w)[5];  // is w high priority?

将导致 processWidget 出现不可预测的行为,这是为什么呢?对 vector <T>operator [] 操作,一般我们期望得到 T& 类型。但是对于 vector <bool>operator [] 操作,得到的是 std::vector<bool>::reference 类型,却不是 bool& 类型。

为什么会有std::vector<bool>::reference 类型呢?主要是以下几个原因:

  1. 为了节省空间,使用 1 个 bit 代替 1 个字节的 bool 类型。
  2. std::vector<T>operator [] 操作应该返回的是 T&, 但标准库无法返对 bit 的引用。
  3. 为了得到接近 bool& 的类型,std::vector<bool>::reference 对象能够使用在 bool& 可以使用的场景。

由于以上几点,再看下这段代码:

bool highPriority = features(w)[5];  // is w high priority?

这里,features 返回的是 std::vector<bool> 对象,然后施加 operator [] 操作得到 std::vector<bool>::reference 对象, 最后被隐式转化为 bool 类型来初始化 highPriorityhighPriority 得到 std::vector<bool>bit 5 的值。

auto highPriority = features(w)[5]; // deduce highPriority's type

bool 换成 auto,由于 auto 的自动类型推导,最后无法得到 std::vector<bool>bit 5 的值。具体是什么值取决于 std::vector<bool>::reference 的实现。std::vector<bool>::reference 的一种实现是这样的:这个对象包含一个指针,这个指针指向一个 wordword 存储了引用的 bit ,加上 wordbitoffset。在这里,features 返回的是一个 std::vector<bool> 临时对象 tempoperator [] 操作后,得到 std::vector<bool>::reference ,它包含一个指向 tempword 的指针,加上 bit 5 的偏移。因此,在语句结尾,临时的 temp 被销毁,highPriority 包含了一个野指针,这将导致 随后的 processWidget 函数的不可预测的行为。

这里可以使用显示类型初始化方式使用 auto

auto highPriority = static_cast<bool>(features(w)[5]);

std::vector<bool>::reference 是代理类(proxy class)的一个例子,代理类的目的是为了模拟和扩展某些其他类型行为,具有广泛的使用,比如标准库的智能指针类型。

在表达式模板中也使用代理类的技术,能够提高数值计算的效率。比如给定一个类 MatrixMatrix 的对象 m1, m2, m3m4,以下表达式:

Matrix sum = m1 + m2 + m3 + m4;

operator + 返回一个代理类对象将更加高效。operator + 两个 Matrix 对象得到代理 Sum<Matrix, Matrix> 对象,而不是Matrix 对象,上面的表达式将得到 Sum<Sum<Sum<Matrix, Matrix>,Matrix>, Matrix> 对象,最后隐式转化为为 Matrix 对象。

这种隐形的代理类遇到 auto 时候往往得不到预期的结果。因此,一般防止出现以下语句:

auto someVar = expression of "invisible" proxy class type;

一种方式是使用显式的类型申明,一种方式是使用 static_cast 显示类型初始化:

bool highPriority = features(w)[5];
auto highPriority = static_cast<bool>(features(w)[5]);

Matrix sum = m1 + m2 + m3 + m4;
auto sum = static_cast<Matrix>(m1 + m2 + m3 + m4);

这样的习惯不仅用于代理类的情况,在定义一个变量的类型及其初始化表达式类型不同时,也最好显式申明变量类型,或者显示类型初始化。例如:

double calcEpsilon(); // return tolerance value

float ep = calcEpsilon(); // impliclitly convert double → float
auto ep = static_cast<float>(calcEpsilon());

最后,总结一下:

  • 隐式的代理类型可能导致 auto 类型推导结果不符合预期。
  • 对于这种代理类型一般使用显式类型申明或者显示类型初始化。
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:58:02  更:2022-02-07 13:58:41 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码