C++程序设计:原理与实践(进阶篇)15.5 再次泛化vector-阿里云开发者社区

开发者社区> 华章出版社> 正文

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的原因是并不写入容器元素,而我们使用&(引用)的原因是以免元素过大拷贝代价太高。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接