Effective C + + clause 47 Please use traits classes performance type information

Source: Internet
Author: User
Tags traits

1. STL Iterator Classification:

Input iterator: Can only be moved forward one step at a time, the customer can only read (not scribble) and can read only once what they refer to, mimicking the reading pointer to the input file. e.g. Istream_iterators

Output iterator: Similar to the input iterator, but "everything is output only", can only be moved forward one step at a time, the customer can only scribble (can't read) and can only scribble once what they point to, mimicking a scribble pointer to the output file. For example, Ostream_iterators.

Forward iterators: All functions with input iterators and output iterators: You can only move forward one step at a time to read or write more than one point. The STL does not provide a single linked list, but some libraries have (usually named Slist), and the iterator to the container is the forward iterator.

Bidirectional iterator: In addition to moving forward, it can be moved backwards, one step only, and can read or write the finger more than once. STL's List,set,multiset,map and Multimap iterators belong to this category.

Random iterator: In addition to all the features of the bidirectional iterator, you can also perform "iterator Arithmetic", which is to move any distance forward or backward in a constant time. An iterator such as Vector,deque and string.

For these five classifications, the C + + standard library provides an exclusive "volume label structure" (tag struct) to differentiate:

struct input_iterator_tag{}; struct output_iterator_tag{}; struct forward_iterator_tag: public input_iterator_tag{}; struct bidirectional_iterator_tag: public forward_iterator_tag{}; struct random_access_iterator_tag: public bidirectional_iterator_tag{};
View Code

2. The STL consists primarily of templates, which is used to represent containers, iterators, and algorithms, and also covers several instrumental templates, such as the advance function template for moving iterators to a given distance. As 1 says, different iterators have different interfaces, Thus advance needs to determine different implementations based on what the different iterators can do, for example, for the random iterator, advance can do the + = operation directly, and for other iterators, it is possible to reuse + + or--, so the implementation of advance might look like this:

 template<typename itert,typename dist>void  Advance (iter& Iter,dist D) { if  (iter is  a random Access iterator) //  pseudo-code  iter+=d;  else  if  (D>=0  )  while  (D--)  ++iter;  else  while  (d++) --iter;}  
View Code

This approach must first determine if ITER is a random iterator, so it is necessary to obtain information about the type, and traits technology is used to enable some of the STL's generic algorithms to obtain certain types of information at compile time.

"Traits is not a C + + keyword or a pre-defined component; they are a technique and a protocol that a C + + programmer adheres to." One of the requirements of this technique is that it must behave as well as the built-in types and user-defined types. "

"Traits can be implemented in a built-in type" means that the type's traits information must be outside the type itself, because it is not possible to judge by the types of nested information implemented in the type. The standard technique is to put it into a template and one or more of the special versions. " There are several templates in the standard library, where the iterator is named iterator_traits ":

Template<typename itert>struct iterator_traits;

Iterator_traits operation is: For each type of itert, within the struct iterator_traits<itert> must declare a typedef named Iterator_catagory, This typedef is used to determine the iterator classification of ITER:

For custom types, it requires that each user "custom iterator type" must be nested with a typedef named Iterator_catagory (in fact, to enable the custom iterator to support more STL generic algorithms, additional typedef is required, See 3rd), this typedef is used to confirm the classification of ITER, so the class designed for a true iterator might recall this:

Template<...>class  deque{public:    class  iterator{     public:        typedef random_access_iterator_tag iterator_category;        ...    };    ...}
View Code

The list iterator might look like this:

Template<...>class  list{public:    class  iterator{     public:         typedef bidirectional_iterator_tag iterator_category;        ...    };    ...};
View Code

As for iterator_traits, it is just a nested typedef used to represent the iterator class:

Template<typename itert>struct  iterator_traits{    typedef typename ITERT::ITERATOR_ Category Iterator_category;    ...};  
View Code

For pointer iterators, because pointers cannot be nested typedef,iterator_traits specifically provides a partial version of the pointer type:

Template<typename iter>struct iterator_traits<itert*>{    typedef random_access_ Iterator_tag iterator_category;    ...};
View Code

From the above example, the design and implementation process of trait classes is as follows:

1). Confirm certain types of information you want to obtain. (for iterators, including their category)

2). Select a name for this information (for the category of the iterator, the name is Iterator_category)

3). Provide a template and a set of special versions (for example, iterator_traits) that contain the type information that you want to support.

Therefore, the first pseudo-code can be implemented:

Template<typename itert,typename dist>void advance (iter& iter,dist d) {    if( typeID (typename::std::iterator_traits<itert>:: iterator_category       = =typeID (typename::std: : Random_access_iterator_tag))    ...}
View Code

This is not the end, because there is a compilation problem with the above code: assume the following call to advance:

std::list<int>:: Iterator Iter;advance (ITER,ten);

Then advance will be transformed into the following form:

voidAdvance (std::list<int>::iterator ITER,intd) {if(typeID (typename::std::iterator_traits<std::list<int>::iterator>:iterator_category==typeid (Typename::std::random_access_iterator_tag)) ITER+=d;//error, compile time does not pass!    Else        if(d>=0)             while(d--)                ++ITER; Else             while(d++)                --iter;}
View Code

Although the test typeid line will always fail because of list<int>::iterator, so Iter+=d never execute, but before this compiler must ensure that all the source code is valid, even if it is not executed!

In addition, since the iterator_traits<itert>::category can be determined at compile time, the judgment of the IF statement is approved at runtime, which not only wastes time, but also causes the executable file to swell.

In fact, C + + provides a way to complete the verification process at compile time: function overloading. Two overloaded functions are synthesized, but different iterator_category objects are accepted, and the actual functionality of the advance is performed by them, so the final implementation version of advance is as follows:

Template<typename Itert,typename distt>voidDoadvance (itert&iter,dist D,std::random_access_iterator_tag) {iter+=D;} Template<typename Itert,typename distt>voidDoadvance (itert&iter,dist D,std::bidirectional_iterator_tag) {    if(d>=0)         while(d--)            ++ITER; Else         while(d++)            --iter;} Template<typename Itert,typename distt>voidDoadvance (itert&iter,dist D,std::input_iterator_tag) {    if(d<0)        ThrowOut_of_range ("Negative Distance");  while(d--)        ++iter;} Template<typename Itert,typename distt>voidDoadvance (iter&iter,dist D) {doadvance (iter,d,typename std::iterator_traits<IterT>:: Iterator_category ());}
View Code

The input_iterator version of Doadvance can also be called by forward iterator because of the inheritance relationship of the previous iterator volume label structure.

From the above example, the use of trait classes is as follows:

1). Create a set of overloaded functions (identity like Labor) or function templates (such as doadvance), the difference between each other is only the respective traits parameters. Each function implementation code and its acceptance of the traits corresponding and.

2). Create a control function (identity like foreman) or function template (for example, advance), which invokes the "labor function described above and transmits the information provided by traits classes".

3. Traits is widely used in the standard library, including the above iterator_traits, in addition to the Iterator_category,iterator_traits also provides four sub-iterators related information (value_type indicates the object type of the iterator, Difference_type indicates the iterator distance type, pointer indicates the object's native pointer type, reference indicates the object's reference type, and references http://www.cnblogs.com/tracylee/archive/2012/ 10/26/2741907.html) There is also char_traits for storing information about character types, numeric_limits for storing information about numeric types, and so on.

TR1 imports many new traits classes to provide type information, including is_fundamental<t> (judging if T is a built-in type),is_array<t> (judging if T is an array type), is_base_of <T1,T2> (Judging whether t1,t2 is the same, or T1 is T2 base classes). Total TR1 added more than 50 trait classes for C + +.

Effective C + + clause 47 Please use traits classes performance type information

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.