标准模板库

原创 2004年01月20日 21:00:00

这篇文章翻译自SGI的网站,原文名为Introduction to Stand Template Library,链接为http://www.sgi.com/tech/stl/.我看后感觉对于理解一些相关概念和学习STL很有帮助就把它翻译过来了,是中英文对照的,因为我也不敢保证完全能表达原文意思,只是按自己的理解翻译出来了,希望对大家能有点帮助.

标准模板库简介(一)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

标准模板库,或者STL,是一个包含容器类(container classes),算法(algorithms),和迭代器(iterator)C++类库.它提供了许多计算机科学中的基本算法和数据结构.STL是一个泛型库,也就是说它的组件都是大量参数化了的(heavily parameterized):STL中的几乎每个组件都是一个模板.在开始使用STL之前,你应当确信你明白C++中的模板是如何运作的.

容器和算法

和许多类库一样,STL包括了容器:它的目的是容纳其它对象.STL包含了vector,list,deque,set,multiset,map,multimap,hash_set,hash_multiset,hash_maphash_multimap.这些类中的每一个都是一个模板.可以被实例化来容纳任何类型的对象.例如,你可以以与使用一个普通的C数组极其相似的方式来使用vector<int>,,除了vector消除了手工管理动态内存分配之外.

vector<int> v(3);           //声明一个有三个元素的vector

v[0] = 7;

v[1] = v[0]+3;

v[2] = v[0]+v[1];          //v[0]=7,v[1]=10,v[2]=17

STL也包含了大量的算法来操纵存储在容器中数据.例如,通过使用reverse算法,你可以反转一个vector中的元素顺序.

reverse(v.begin(),v.end());     //v[0]=17,v[1]=10,v[2]=7

对于reverse的这个调用有两点值得注意.首先,它是一个全局函数,而不是一个成员函数.第二,它接受两个参数而不是一个:它操作一系列元素,而不是一个容器.在这个例子中元素范围刚好是整个容器v.

导致这两个事实的原因都是一样的:reverse,像其它STL算法一样,是与STL容器类分离的,也就是说,reverse不仅可以用来反转vector中的元素,而且可以反转list甚至C数组中的元素.下面的程序也是有效的:

double A[8] = {1.2,1.3,1.4,1.5,1.6,1.7};

reverse(A,A+6);

for(int I = 0;i < 6;i++)

       cout << “A[“ << I << “]=” << A[i];

这个例子使用了一个范围(range),就如反转一个vector的例子一样;reverse的第一个参数是一个指向该范围的开始指针,第二个参数指向该范围最后一个元素之后的位置.这个范围以[A,A+6]来标记;这个非对称的标记是用来提醒那两个端点是不同得,第一个是该范围的开始,第二个则是范围末尾之后的位置.

迭代器(Iterators)

在反转一个C数组的例子中,reverse的参数类型明显的是double*.但是如果反转一个vector或者一个list的话reverse的参数又是什么呢?reverse所声明的参数究竟是什么,以及v.begin()v.end()究竟返回的是什么?

The answer is that the arguments to reverse are iterators, which are a generalization of pointers. Pointers themselves are iterators, which is why it is possible to reverse the elements of a C array. Similarly, vector declares the nested types iterator and const_iterator. In the example above, the type returned by v.begin() and v.end() is vector<int>::iterator. There are also some iterators, such as istream_iterator and ostream_iterator, that aren't associated with containers at all.

答案就是reverse的参数为iterators,它是指针的一个泛化(generalization).指针自身就是是迭代器(iterator),所以才有可能反转一个C数组的元素.相似的,vector声明了内嵌类型(nested type)iteratorconst_iterator.在上面的例子中,v.begin()v.end()所返回的类型是vector<int>::iterator.还有一些迭代器(iterators),例如istream_iteratorostream_iterator与容器根本就没有关联.

Iterators are the mechanism that makes it possible to decouple algorithms from containers: algorithms are templates, and are parameterized by the type of iterator, so they are not restricted to a single type of container. Consider, for example, how to write an algorithm that performs linear search through a range. This is the STL's find algorithm.

迭代器(iterators)是一种使得将算法与容器进行分离成为可能的机制:算法是模板,用迭代器的类型进行参数化,所以它们并不限于单一类型的容器.例如,考虑怎样编写一个在一个范围内执行线性搜索的算法.这就是STLfind算法.

              Template<class InputIterator, class T>

              InputIterator find(InputIterator first, InputIterator last, const T& value) {

                     While(first != last && *fist != value) ++first;

                     Return first;

              }

Find takes three arguments: two iterators that define a range, and a value to search for in that range. It examines each iterator in the range [first, last), proceeding from the beginning to the end, and stops either when it finds an iterator that points to value or when it reaches the end of the range.

Find接受三个参数:两个规定了一个范围的迭代器和在该范围内要搜寻的一个值value.它在[first,last]范围内检查每一个迭代器,从开始到最后,当它找到一个指向value的迭代器或者达到末尾时就停止了.

First and last are declared to be of type InputIterator, and InputIterator is a template parameter. That is, there isn't actually any type called InputIterator: when you call find, the compiler substitutes the actual type of the arguments for the formal type parameters InputIterator and T. If the first two arguments to find are of type int* and the third is of type int, then it is as if you had called the following function.

Concepts and Modeling

One very important question to ask about any template function, not just about STL algorithms, is what the set of types is that may correctly be substituted for the formal template parameters. Clearly, for example, int* or double* may be substituted for find's formal template parameter InputIterator. Equally clearly, int or double may not: find uses the expression *first, and the dereference operator makes no sense for an object of type int or of type double. The basic answer, then, is that find implicitly defines a set of requirements on types, and that it may be instantiated with any type that satisfies those requirements. Whatever type is substituted for InputIterator must provide certain operations: it must be possible to compare two objects of that type for equality, it must be possible to increment an object of that type, it must be possible to dereference an object of that type to obtain the object that it points to, and so on.

 

Find isn't the only STL algorithm that has such a set of requirements; the arguments to for_each and count, and other algorithms, must satisfy the same requirements. These requirements are sufficiently important that we give them a name: we call such a set of type requirements a concept, and we call this particular concept Input Iterator. We say that a type conforms to a concept, or that it is a model of a concept, if it satisfies all of those requirements. We say that int* is a model of Input Iterator because int* provides all of the operations that are specified by the Input Iterator requirements.

 

Concepts are not a part of the C++ language; there is no way to declare a concept in a program, or to declare that a particular type is a model of a concept. Nevertheless, concepts are an extremely important part of the STL. Using concepts makes it possible to write programs that cleanly separate interface from implementation: the author of find only has to consider the interface specified by the concept Input Iterator, rather than the implementation of every possible type that conforms to that concept. Similarly, if you want to use find, you need only to ensure that the arguments you pass to it are models of Input Iterator. This is the reason why find and reverse can be used with lists, vectors, C arrays, and many other types: programming in terms of concepts, rather than in terms of specific types, makes it possible to reuse software components and to combine components together.

概念并不是C++语言的一部分;没有办法在一个程序中声明一个概念,或者声明一个特定类型为一个概念的一个模型.然而,概念是STL的一个极度重要的部分.使用概念使得编写将接口与实现明确分离开的程序成为可能:find的作者只需考虑由概念Input_Iterator所指定的接口,而不用考虑遵循该概念的每个可能的类型.相似的,如果你想使用find,你只需确保你所传递的参数是Input_Iterator的模型.这就是为什么find和reverse可以用于list,vector,C数组和许多其它类型的原因:根据概念(concept)而不是特定类型来编程使得我们可以重用软件组件和将组件联合在一起.

C++标准模板库STL算法与自适应容器(栈和队列)

参考《21天学通C++》第23与第24章节,对STL算法与自适应容器进行介绍。 实际上在前面的STL顺序容器、关联容器进行介绍时或多或少引用到了一些STL算法中的模板函数。而自适应容器是在顺序容器的基...
  • LG1259156776
  • LG1259156776
  • 2015年08月06日 13:22
  • 1821

C++ STL标准模板库

标准模板库 STL(StandardTemplate Library),即标准模板库,是一个具有工业强度的、高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Librar...
  • qq563129582
  • qq563129582
  • 2015年02月27日 16:32
  • 1246

几个标准模板库常用功能示例

1. 对std::map按key查找 方法: bool map_finder_by_key(std::pair aPair, CString strKey) { return 0 == ...
  • a_dev
  • a_dev
  • 2017年03月09日 15:52
  • 242

C++标准库和C++标准模版库

     C++标准库很大,在现在的情况下,C++标准库确实越来越好,因为大的库会包含大量的功能.标准库中的功能越多,开发自己的应用程序时能借助的功能就越多,C++库并非提供一切(很明显的是没有提供开...
  • Molany
  • Molany
  • 2008年11月25日 16:55
  • 4499

C++ 标准模板库(STL)汇总

C++ 标准模板库(STL)汇总
  • DaveBobo
  • DaveBobo
  • 2017年02月22日 21:08
  • 775

使用标准模板库 (STL)之一

STL STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括...
  • u010236550
  • u010236550
  • 2013年10月08日 21:53
  • 1118

标准模板库STL详解之vector

泛型是标准模板库(STL)的核心思想,常用STL组件主要有算法,函数对象,容器和迭代器。STL泛型算法具有相似的操作接口。借助于迭代器,程序能够以方便统一的形式访问不同的数据类型,不同存储形式的元素。...
  • qq_33371343
  • qq_33371343
  • 2016年05月31日 10:49
  • 360

标准模板库(list)

对list的理解: 1.list不支持随机访问,只支持顺序访问。 2.size用于获得list的节点个数,clear用于清空list。 3.front和back分别得到首部元素和尾部元素。 #...
  • fu_yunjian
  • fu_yunjian
  • 2016年09月30日 16:35
  • 219

用标准模板库定义小顶堆,求哈夫曼树带权和

用标准模板库定义小顶堆,求哈夫曼树带权和 要求:输入一个整数n,在输入n个整数,输出带权和 输入样例:5      1 2 2 5 9 输出样例:     37 实现代码: #i...
  • m0_37036984
  • m0_37036984
  • 2018年01月06日 14:51
  • 52

[C++标准模板库:自修教程与参考手册]关于vector

什么是vector可以这样认为,vector就是一个动态的数组,其中的元素必须具备assignable(可赋值)和copyable(可拷贝)两个性质。 vector的一些重要的性质 vector支持...
  • m0_37316917
  • m0_37316917
  • 2017年07月20日 21:55
  • 181
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:标准模板库
举报原因:
原因补充:

(最多只允许输入30个字)