## CSDN博客

### 标准模板库

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

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];

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.

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;
      }

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.

0 0