C ++ technology used by STL (2) -- Special Template

Source: Internet
Author: User

STL is an important part of the C ++ standard library. It is not only a reusable component library, but also a software framework that contains algorithms and data structures, it is also a good example of C ++ generic programming. Many advanced C ++ technologies are used in STL. This article describes the application of the template-specific technology. Mainly refer to "C ++ Primer" and "STL source code analysis".

STL uses a lot of modules. It can be said that templates are formulas for creating classes or functions. However, we cannot always write out templates that are most suitable for all types that may be instantiated. Here is an example of function template specialization.

Template <typename T> <br/> int Compare (const T & x, const T & y) <br/>{< br/> if (x <y) <br/> return-1; <br/> else if (x> y) <br/> return 1; <br/> else <br/> return 0; <br/>}

For the above function template, if two string pointers are used for calling, the pointer value is compared, that is, the address size is compared, rather than the string size. Therefore, to use the Compare function for strings, you need to provide a special definition of how to Compare C-style strings. This is template specialization.

Template specialization is defined as the actual type or actual value of one or more template parameters. For example, you can define a special version for the Compare template function.

Template <> // empty parentheses followed by the template keyword <br/> int Compare (const char * const & x, const char * const & y) // reference a constant pointer pointing to a constant <br/>{< br/> return strcmp (x, y); <br/>}< br/>

The previous section briefly describes the template features. Now we will introduce the application of the template features in STL, and take the application of the iterator as an example.

The iterator is the key to STL. It binds the originally separated Data containers and algorithms. For example, the following STL function (from the source code) is renamed and some code is omitted, but it is sufficient to explain the problem. This function exchanges container data through the iterator. The iterator serves as a bridge between the data container and the algorithm. The algorithm accesses the data in the container through the iterator of the Data container without worrying about the specific structure of the container.

// Real exchange function, internal call <br/> template <class Iter1, class Iter2, class T> <br/> inline void _ iter_swap (Iter1 a, Iter2 B, t) {<br/> T tmp = * a; <br/> * a = * B; <br/> * B = tmp; <br/>}< br/> // exchange the elements referred to by the two iterators, external interface <br/> template <class Iter1, class Iter2> <br/> inline void iter_swap (Iter1 a, Iter2 B) {<br/> _ iter_swap (a, B, VALUE_TYPE (Iter1 )); // VALUE_TYPE: return the iterator Value Type <br/>}

The above uses a VALUE_TYPE call, which is the value type of the returned iterator. The details are described below. This example is used to call the API. This article focuses on Template specialization, but it seems that the problem has been solved here, Yun. The course is almost complete.

To ask a question, the iter_swap function is an iterator. We need to define a temporary variable within the function. The data type of the variable is the data type referred to by the iterator. So how do we know the data type referred to by the iterator? Some people say that the real parameter Inference Mechanism of the template can be used to solve this problem. The Code is as follows:

// Real exchange function <br/> template <class Iter1, class Iter2, class T> <br/> inline void _ iter_swap (Iter1 a, Iter2 B, T) {<br/> T tmp = * a; <br/> * a = * B; <br/> * B = tmp; <br/>}< br/> // exchange the elements referred to by the two iterators <br/> template <class Iter1, class Iter2> <br/> inline void iter_swap (Iter1 a, Iter2 B) {<br/> _ iter_swap (a, B, * ); // real parameter inference for the template <br/>}However, if you want to deduce the return type of the function, the real parameter Inference Mechanism of the template becomes invalid. The specific content of the Real-Time Parameter Inference Mechanism of the template will be described in this series (3. Continuing with the above problem, this article uses a call called VALUE_TYPE to obtain it. It is like an extraction agent that extracts the data type referred to by the iterator. How is it implemented? The answer is the nested type. In STL, most containers require defining the embedded type of the iterator. below is the definition in list, which has been simplified.

Class MyAlloc {<br/>}; </p> <p> template <class T> <br/> struct List_iterator {<br/> typedef T value_type; // list iterator embedded type <br/>... <br/>}; </p> <p> template <class T, class Alloc = MyAlloc> <br/> class list {<br/> public: <br/> typedef List_iterator <T> iterator; // list iterator <br/>... <br/> };In this way, the data types referred to by the list iterator can be extracted.

Template <class I> <br/> struct Iterator_traits {// extraction agent definition <br/> typedef typename I: value_type; <br/> }; </p> <p> Iterator_traits <list <int >:: iterator >:: value_type x = 1;This method can only extract the defined nested iterator. But if it is a native pointer, is it not nested? For example, a vector container uses a native pointer as an iterator. Definition:

Class MyAlloc {<br/>}; </p> <p> template <class T, class Alloc = MyAlloc> <br/> class vector: <br/>{< br/> public: <br/> typedef T value_type; // embedded type <br/> typedef value_type * pointer; <br/> typedef const value_type * const_pointer; <br/> typedef value_type * iterator; // vector iterator, which is a native pointer <br/> typedef const value_type * const_iterator; <br/> typedef value_type & reference; <br/> typedef const value_type & const_reference; <br/>... <br/> };The template special feature is finally available. The support for native pointers is added below. It uses the template special technology and adds the special version to the general design. This technology is also the core key of STL.

Template <class I> <br/> struct Iterator_traits {<br/> typedef typename I: value_type; <br/> }; <br/> // native special pointer <br/> template <class T> <br/> struct Iterator_traits <T * >{< br/> typedef T value_type; <br/> }; <br/> // special native regular pointer <br/> template <class T> <br/> struct Iterator_traits <const T * >{< br/> typedef T value_type; <br/> };The complete code is provided below, which has passed the test in VS2008. # Include <iostream> <br/> # include <vector> <br/> # include <list> <br/> using namespace std; </p> <p> // extraction agent <br/> template <class I> <br/> struct Iterator_traits {<br/> typedef typename I: value_type; <br/> }; <br/> // native special pointer <br/> template <class T> <br/> struct Iterator_traits <T * >{< br/> typedef T value_type; <br/> }; <br/> // special native regular pointer <br/> template <class T> <br/> struct Iterator_traits <const T * >{< br/> typedef T value_type; <br/>}; </p> <p> # define VALUE_TYPE (I) Iterator_traits <I >:: value_type () </p> <p> // exchange elements referred to by two iterators <br/> template <class Iter1, class Iter2> <br/> inline void iter_swap (Iter1, iter2 B) {<br/> _ iter_swap (a, B, VALUE_TYPE (Iter1 )); // VALUE_TYPE: return the iterator Value Type <br/>}< br/> // real exchange function <br/> template <class Iter1, class Iter2, class T> <br/> inline void _ iter_swap (Iter1 a, Iter2 B, T) {<br/> T tmp = *; <br/> * a = * B; <br/> * B = tmp; <br/>}< br/> // test the function <br/> int main () <br/>{< br/> int a = 1, B = 2; <br/> iter_swap (& a, & B ); <br/> cout <a <''<B <endl; // 2 1 </p> <p> list <int> l; <br/> l. push_back (3); <br/> l. push_back (4); <br/> iter_swap (l. begin (), ++ l. begin (); <br/> cout <* (l. begin () <''<* (++ l. begin () <endl; // 4 3 </p> <p> Iterator_traits <int *>: value_type w = 5; // special <br/> Iterator_traits <const int *>: value_type x = 6; // special <br/> Iterator_traits <vector <int >:: iterator> :: value_type y = 7; // vector container <br/> Iterator_traits <list <int >:: iterator >:: value_type z = 8; // list container <br/> cout <w <''<x <'' <y <''<z <endl; // 5 6 7 8 <br/> return 0; <br/>}< br/>This article also introduces another key technology of STL iterator implementation-embedded type. The following describes the real parameter Inference Mechanism of the template. Reposted Source

Http://blog.csdn.net/wuzhekai1985

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.