标准模板库

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

标准模板库简介(一)

标准模板库,或者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.

      template <class InputIterator, class T>
      InputIterator find(InputIterator first, InputIterator last, const T& value) {
          while (first != last && *first != value) ++first;
          return first;
      }

迭代器(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.

      int* find(int* first, int* last, const int& value) {
          while (first != last && *first != value) ++first;
          return first;
      }
first和last被声明为类型InputIterator,它是一个模板参数.即,事实上没有任何一个类型叫做InputIterator:当你调用find时,编译器用实际的参数类型来替换形式类型参数InputIterator和T.如果find的头两个参数类型为int*而第三个参数类型为int的话,那么就像你调用了下列函数一样:
   
      int* find(int* first, int* last, const int& value) {
          while (first != last && *first != value) ++first;
          return first;
      }

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.

概念和模型
    
关于模板函数的一个非常重要的问题,不仅是关于STL算法,就是可以正确替换形式模板参数的类型的集合.很明显,例如,int*或者double*可以用来替换find的形式模板参数InputIterator.同样明显的是,int或者double就不可以:find使用表达式*first,解析引用(dereference)操作符对于类型为int或者double的对象并没有任何意义.因此,基本的答案就是find隐含的定义了对于类型的要求,如果这些要求得到满足那么就可以实例化.不管什么类型替换了InputIterator都必须提供一定的操作:必须能够可以比较该类型的两个对象是否相等,必须能够对该类型的一个对象进行增加操作,必须能够对该类型的一个对象进行解析引用操作以获得它所指向的对象等等.
    

 

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.

find并不是有这种要求的唯一一个STL算法;for_each和count以及其它算法的参数都必须满足相同的要求.这些要求都是相当的重要,所以我们给它们一个名字:我们将这种类型要求称为一个概念(concept),并将这种特殊的概念(concept)称为Input_Iterator.我们说一个类型遵循一个概念,或者它是一个概念的一个模型,如果它满足所有那些要求的话.我们说int*是Input_iterator的一个模型,因为int*提供了Input_Iterator要求所指定的所有操作.
   

 

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)而不是特定类型来编程使得我们可以重用软件组件和将组件联合在一起.

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论
一份讲解全面的标准模板STL学习资料 标准模板STL主要由6大组件组成: (1)容器(Containers)。包括各种基本数据结构的类模板。 STL容器部分主要由头文件<vector>、<list>、<deque>、<set>、< map>、<stack>和<queue>组成。 (2)算法(Algorithms)。包括各种基本算法,如比较、交换、查找、排序、遍历操作、复制、修改、移除、反转、合并等等。 STL算法部分主要由头文件<algorithm>和<numeric>组成。 (3)迭代器(Iterators)。迭代器是面向对象版本的指针,如同指针可以指向内存中的一个地址,迭代器可以指向容器中的一个位置。 STL的每一个容器类模板中,都定义了一组对应的迭代器类,用以存取容器中的元素。这样,在STL中迭代器就将算法和容器联系起来了,通过迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型。 STL迭代器部分主要由头文件<utility>和<iterator>组成。 (4)函数对象(Function Objects)。一种行为类似于函数的class,实现技术上是一个改写了“call operator()”的class。 STL 提供 15 个预定义的 Function objects。头文件<functional>中定义了一些类模板,用以声明函数对象。 (5)适配器(Adaptors)。简单地说就是一种接口类,专门用来修改现有类的接口,提供一种新的接口;或调用现有的函数来实现所需要的功能。 主要包括3种适配器Container Adaptors、Iterator Adaptors与Function Adaptors。其中迭代器适配器的定义在头文件<iterator>中,函数适配器的定义在头文件<functional>中。 (6)内存配置器(Allocators)。为STL提供空间配置的系统。 头文件<memory>中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。容器使用allocator完成对内存的操作,allocator提供内存原语以对内存进行统一的存取。
1 STL 简介 ..............................................................................................................................................2 2 顺序性容器...........................................................................................................................................2 2.1 C++ VECTOR(向量容器) ...........................................................................................................2 2.2 C++ LIST(双向链表) .................................................................................................................4 2.3 C++ DEQUE(双向队列) ..................................................................................................................6 2.4 三者比较........................................................................................................................................8 3 关联容器...............................................................................................................................................8 3.1 特点................................................................................................................................................8 3.2 C++ SETS & MULTISETS .................................................................................................................9 3.3 C++ MAPS & MULTIMAPS ............................................................................................................ 11 4 容器适配器.........................................................................................................................................12 4.1 特点..............................................................................................................................................12 4.2 C++ STACKS(堆栈) ..................................................................................................................13 4.3 C++ QUEUES(队列) ......................................................................................................................13 4.4 C++ PRIORITY QUEUES(优先队列)...............................................................................................13 5 迭代器.................................................................................................................................................14 5.1 解释..............................................................................................................................................14 5.2 功能特点......................................................................................................................................14 6 C++标准总结..................................................................................................................................15 6.1 容器..............................................................................................................................................15 6.2 算法..............................................................................................................................................15 6.3 函数对象......................................................................................................................................17 6.4 迭代器..........................................................................................................................................19 6.5 分配器..........................................................................................................................................19 6.6 数值..............................................................................................................................................19

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Cppasm

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值