STL iterators and type extraction

Source: Internet
Author: User
Tags traits

Today you can put the implementation of the STL library iterator, and the type extraction well tidy up

The design thinking of iterators is the key to STL, in the actual use of STL and generic thinking, iterators play a very important role, STL is trying to separate the concept of data containers and algorithms, so there are two parts of the STL, Containers (container) and generic algorithms (algorithms), the generic algorithm has many parameters that are iterators.

Give me a chestnut! The implementation of the generic algorithm find ()!

1template<classInputiterator,classT>2Inputiterator Find (inputiterator First, Inputiterator last,Constt&value)3 {4      while(*first! = *last && *first! =value)5     {6++First ;7     }8     returnFirst ;9}

Parameters that accept two input iterators

    • STL divides an iterator into 5 categories
      • Trivial iterator (Trivial Iterator): Just a concept that distinguishes the definition of all iterators
      • Input iterator: Provides a read-only operation that reads the value of its point to the element, but cannot change the value of the element (also including all operations in the trivial iterator, perhaps with inheritance? ))
      • Output Iterator: Provides write-only operation to change
      • Forward iterator (Forward Iterator): The value of the pointed element can be changed, but cannot be read
      • Bidirectional iterators (bidirectional Iterator): Can be moved in both directions
      • Random-access iterators (Iterator): Han Hu A variety of pointer arithmetic capabilities that can be accessed randomly like a sequential table

A previously released smart pointer is also a kind of iterator, the native pointer of course can also be said to be an iterator, but that is a bit of a narrow iterator definition, because the custom type of pointer function is not perfect, need to overload some operators and so on, why the smart pointer is not directly used as an iterator? Because you can't get the type that the smart pointer points to!

Why do you say that? Because sometimes we might want to use the type pointed to by the smart pointer to create some variables, bad, even if the use of type_id also just get the name, and can not be used to create variables, there is a way to use the

1template<classTclassU>2  3 voidFun_impl (T T, u u)4 5 {6 7U tmp;//we got the type8 9 }Tentemplate<classT> One  A voidFun (T t) -  - { the  -                  returnFun_impl (T, *t); -  -}

In doing so, you can get the type you are pointing to (and create the desired variable), but what should we do when we need a return value like this, perhaps this way? Seems to be so perfect, but after compiling the ruthless crush of your hope, compilation is not passed

But we can get their type through inline type declarations (through typeID, because typeID can only get the name of the type and cannot declare the variable with that name)

This method is obviously possible, but there is a subtle trap, because not all of the passed is an iterator, in case the pass is a native pointer , the native pointer does not have an embedded type (of course, you think a int* inside will have an embedded type, Say int* have what inside?!!! It's going to use a special knowledge.

So what is a partial specificity? When using templates, the template parameter is set to multiple Template<class T, and the class u> template can be specific

1template<classTclassU>2 classClass13 {4 T A;5 U B;6 };7template<classT>8 classclass1<int>9 {Ten T A; One U B; A};

You are special in the code above, eh! Easy to understand, if T is also special, is full of special, the partial special is not all special!

But there is also a problem, when the passed pointer is a pointer to the constant value (pointers to const) const int *PTR, we obviously get the type is the const int, this is something wrong, Because we get the type to declare the temporary variable is no way to use, because he pointed to the constant value, very simple, and then take the partial specificity of it (that is, in <T*> to <const t*>)

Traits plays the role of a type extractor to extract the type that the iterator points to (type extraction?!). )

Why should there be so many iterators? You look at the container! Because the iterator has the implementation of operator++, each container stored in a different way, vector is stored sequentially, list is chained storage, operator++ internal implementation is certainly not the same, but also want to generic programming, inherit, package slightly ...

    • There are 5 types of iterators that are most commonly used: value_type,difference_type,pointer,reference,iterator_category
      • Value_type is the type of object that the iterator points to, and each iterator should define its own Value_type inline type
      • The difference_type is used to represent the distance between two iterators, so it can also represent the maximum capacity of a container
      • Referecne reference? Lvalue, because there is a need for a const iterator, this time requires an iterator that cannot change the object to which it is directed; in C + +, a function that returns an lvalue is done by reference
      • Pointer_type is the address of the object to which the simple iterator is pointing, which is the second
      • Iterator_category is the type of extraction previously used, extraction of the name of the iterator, as a function parameter, the activation function overload mechanism, is the use of traits implementation of the

So I'm going to talk about Iterator_category.

What's iterator_category doing? Classify and identify the five types of iterators

The arrows in this diagram do not represent the inheritance, but the concept of strengthening the relationship, that is, the lower layer must be an upper layer, but the upper layer is not a lower layer, and the square is a special kind of rectangle, but the rectangle is not a square

 1  struct   Input_iterator_tag {};  2  struct   Output_iterator_tag {};  3  public   Input_iterator_tag {};  4  public   Forward_iterator_tag {};  5  public  Bidirectional_iterator_tag {}; 

This is a five-shell structure, and no other use is to identify the iterator type, which activates the function overloading mechanism (because the parameters required in the generic algorithm will be given to the topmost type only, so that when called, the underlying iterator is also accepted)

Why is there inheritance? A generic algorithm is a formal parameter that supports an upper-level iterator as a parameter into the underlying iterator! It is used here because the iterator itself does not inherit, so the overloaded mechanism is activated with the identity name inheritance

For example advance (iterator, n) generic function, its role is to pass over the iterator back to N, each iterator implementation is certainly not the same, like Forward_iterator can only one walk, walk n times, Bidirectional_ Iterator also, Random_access_iterator can go for a walk n, if written a, will certainly affect the efficiency of random_access_iterator, so separate write, then how do I know which function to call? Because I want generic programming (that is, I am lazy, I want to save the trouble) must want to write only a function name, pass a parameter, let the program help me choose which function to call (my God!). This is not a function overload, but the program needs to know what type of iterator I'm passing (which is type extraction!!!). Extract the type from the iterator! (not full, other similar)

The last one in the argument list is the five empty shell structure you just built!! Call _advance when the last parameter to the iterator iterator_category on the line, right! Yes, that's it! Let the program decide which function to use!!

Specific implementation: Call

 1  template <class  Inputiterator , class  distance>2  inline void  Advance (inputiterator& i,distance N)  3  4  _advance (i, N, iterator_traits<inputiterator>::iterator_category ()); /span>5 } 
1 template<class i>2struct3{
... 4 typedef typename I::iterator_category iterator_category; 5 };

STL iterators and type extraction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.