C++程序设计:原理与实践(进阶篇)15.5 再次泛化vector

15.5 再次泛化vector


显然,通过15.3~15.4节的例子我们发现,标准库vector包含一个iterator成员类型,以及begin()和end()成员函数(与std::list类似)。然而,我们并没有在第14章中为vector类提供这些成员。那么,对于不同类型的容器而言,它们究竟采用了什么方法,以使它们或多或少地能够在15.3节所介绍的STL泛型编程风格中相互替换使用?首先,我们将简要介绍一种解决方案(简单起见,我们忽略了分配器),然后再对解决方案进行解释:

 

 

 

using声明为一个类型创建别名,即对于我们的vector,iterator是我们用作迭代器类型T*的一个同义词,它的另一个名字。现在,对于vector对象v,我们可以编写如下代码:

 

以及

 

通过别名的方式,我们事实上不需要知道iterator和size_type的实际类型。特别地,由于使用了iteartor和size_type,上述代码也可以用于那些size_type不是unsigned long类型(在很多嵌入式系统中,size_type为其他类型)并且iterator为类而不是简单指针(这种情况在C++实现中很普遍)的vector。

标准库以相似的方式定义了list和其他标准容器。例如:

 

 

这样,我们编写代码时就不必操心使用的是list还是vector。所有标准库算法中都使用了上述这些容器的成员类型名,例如iterator和size_type,所以,算法的实现不依赖于容器的实现或者具体操作的是什么容器(参见第16章)。

还有一种方法可以替代对容器C使用C::iterator——Iterator<C>,这也是我们通常更倾向使用的方法。通过一个简单的模板别名即可实现这种用法:

 

出于语言技术层面的原因,我们需要为C::iterator加上typename前缀,以表明iterator是一个类型,这也是我们更倾向于使用Iterator<C>的原因之一。类似地,我们可以定义

 

这样,我们就可以在代码中使用Value_type<C>了。这些类型别名不包含在标准库中,但你可以在std_lib_facilities.h中找到它们。

using声明是C++11的新特性,与C和C++中为人熟知的typedef(见附录A.16)相似,可以看作后者的泛化。

15.5.1 遍历容器

使用size(),我们可以从头到尾遍历一个vector。例如:

 

这段代码不适用于链表,因为list不提供下标操作。但是,我们可以用一个简单的范围for循环(见4.6.1节)来遍历标准库vector和list。例如:

 

这段代码既适用于标准库容器,也适用于“我们的”vector和list。它是如何办到的?“窍门”在于范围for循环是基于begin()和end()函数的,前者返回指向我们的vector的首元素的迭代器,后者返回指向尾元素之后位置的迭代器。范围for循环其实不过是使用迭代器遍历序列的循环的一种“语法糖衣”而已。如果我们为自己的vector和list定义了begin()和end(),就“偶然地”提供了范围-for所需要的东西。

15.5.2 auto

当我们不得不编写循环遍历一个通用结构时,命名迭代器是很令人厌烦的事情。考虑下面代码:

 

这里最恼人的地方是编译器显然已经知道了list的iterator类型和vector的size_type。我们为什么还必须告诉编译器它已经知道的事情呢?这样做徒增我们当中不擅打字的人的烦恼,并增加出错的机会。幸运的是,我们无须这样做:可以将变量声明为auto的,表示使用iterator类型作为变量的类型:

 

这里,p是一个vector<T>::iterator,q是一个list<T>::iterator。我们几乎可以在任何包含初始化器的定义中使用auto。例如:

 

注意,字符串字面值常量的类型为const char*,因此对字符串字面值常量使用auto可能导致令人不快的意外:

 

当我们确切知道想要的类型时,通常指明类型和使用auto一样容易。

auto的常见用途是在范围for循环中指明循环变量。考虑下面代码:

 

在这段代码中,我们使用auto的原因是给出容器cont的元素类型不是那么容易。我们使用const的原因是并不写入容器元素,而我们使用&(引用)的原因是以免元素过大拷贝代价太高。

时间: 2024-09-18 21:46:21

C++程序设计:原理与实践(进阶篇)15.5 再次泛化vector的相关文章

c++-关于《C++程序设计原理与实践》第3章例子的一个问题

问题描述 关于<C++程序设计原理与实践>第3章例子的一个问题 本人菜鸟,现正在学习C++.<C++程序设计原理与实践>第3章有一个例子,代码如下: #include #include #include #include #include using namespace std; inline void keep_window_open(){ char ch; cin >> ch; } int main() //C++ Programs start by executi

源代码-C++程序设计原理与实践

问题描述 C++程序设计原理与实践 #include "std_lib_facilities.h" int main() { cout<<"Hello,world!n"; return 0; } 我下了源代码,放到那里才能猜VC98编译时不出错?最好详细点,带有图解 解决方案 ...大哥,都什么年代了还用98

《 C++程序设计:原理与实践(进阶篇.》导读

本节书摘来自华章出版社< C++程序设计:原理与实践(进阶篇)>一书中作者[美] 本贾尼·斯特劳斯特鲁普(Bjarne Stroustrup) 著 刘晓光 李忠伟 王刚 译     前 言 Programming: Principles and Practice Using C++, Second Edition 该死的鱼雷!全速前进. --Admiral Farragut 程序设计是这样一门艺术,它将问题求解方案描述成计算机可以执行的形式.程序设计中很多工作都花费在寻找求解方案以及对其求精上

C++程序设计:原理与实践(进阶篇)15.8 调整vector类达到STL版本的功能

15.8 调整vector类达到STL版本的功能 在15.5节中为vector增加了begin().end()和类型别名后,现在只差insert()和erase()就接近我们设计一个std::vector的近似版本的目标了:   我们还是使用指向元素类型的指针T*作为迭代器的类型,这是最简单的方法.我们将边界检查迭代器的实现留作练习(习题18). 人们通常不会为元素连续存储的数据类型(如vector)提供列表操作,如insert()或erase().但insert()和erase()这样的列表操

100分求java语言程序设计进阶篇pdf

问题描述 求java语言程序设计进阶篇pdf 解决方案 解决方案二:同求啊!!!解决方案三:这个网上是没有的,我也在网上找过,我建议你去网上找java核心技术<上下卷>pdf这本书写的也是不错的,,这个网上有电子书的,,这两本书配合着java编程思想,相当的不错的解决方案四:真正的进阶是需要项目练习的,纸上得来终觉浅解决方案五:引用2楼xinzailiulei的回复: 这个网上是没有的,我也在网上找过,我建议你去网上找java核心技术<上下卷>pdf这本书写的也是不错的,,这个网上

学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践

原文 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践 感谢大家在上一篇 学一点Git--20分钟git快速上手 里的踊跃发言.这里再次分享干货, 简单介绍mysql双机,多机异地热备简单原理实战. 双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一 致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换到另一个. 2. 可以做负载均衡,可以将请求分摊到其中任何一台上

推荐系统——从原理到实践,还有福利赠送!

之前流水账似的介绍过一篇机器学习入门的文章,大致介绍了如何学习以及机器学习的入门方法并提供了一些博主自己整理的比较有用的资源.这篇就尽量以白话解释并介绍机器学习在推荐系统中的实践以及遇到的问题... 也许很多点在行家的眼里都是小菜一碟,但是对于刚刚接触机器学习来说,还有很多未知等待挑战. 所以读者可以把本篇当做是机器学习的玩具即可,如果文中有任何问题,还请不吝指教. 本篇将会以下面的步骤描述机器学习是如何在实践中应用的: 1 什么是推荐系统? 2 机器学习的作用 3 机器学习是如何使用的? 4

Node.js Stream - 进阶篇

上篇(基础篇)主要介绍了Stream的基本概念和用法,本篇将深入剖析背后工作原理,重点是如何实现流式数据处理和 back pressure 机制. 目录 本篇介绍 stream 是如何实现流式数据处理的. 数据生产和消耗的媒介 为什么使用流取数据 下面是一个读取文件内容的例子: const fs = require('fs') fs.readFile(file, function (err, body) { console.log(body) console.log(body.toString(

SQL Server调优系列进阶篇(如何索引调优)

原文:SQL Server调优系列进阶篇(如何索引调优) 前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本篇我们就开始分析这块内容,关于索引的基础知识就不打算深入分析了,网上一搜一片片的,本篇更侧重的是一些实战项内容展示,希望通过本篇文章各位看官能在真正的场景中找到合适的解决方法足以. 对于索引的使用,我希望的是遇到问题找到合适的解决方法就可以,