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 topic describes how to use real-time parameter inference for a template. Mainly refer to "C ++ Primer" and "STL source code analysis".
STL is implemented using template templates. For example, its algorithms are all function templates. We know that a template is a formula or blueprint. It is not a class or function and needs to be instantiated. This process is completed during the compilation period. The Compiler deduce the type of the parameter based on the passed real parameters and instantiate the corresponding function. Definition in C ++ Primer: the process of determining the type and value of the template's real parameters from the function arguments is called template argument deduction ). The following describes several algorithms in STL. The names are modified and some code is omitted.
// Small value <br/> template <class T> <br/> inline const T & Min (const T & a, const T & B) {<br/> return B <? B:; <br/>}< br/> // relatively strong <br/> template <class T> <br/> inline const T & Max (const T &, const T & B) {<br/> return a <B? B: a; <br/>}
In the following scenarios, the compiler will instantiate two versions of Min based on real parameters.
Int main () <br/>{< br/> cout <Min (1.2) <endl; <br/> cout <Min (3.2) <endl; <br/> return 0; <br/>}
Inline const int & Min (const int & a, const int & B) {<br/> return B <? B: a; <br/>}< br/> inline const double & Min (const double & a, const double & B) {<br/> return B <? B: a; <br/>}
The description above is relatively simple. For details, see C ++ Primer. This article only paves the way. In the previous article "C ++ technology used by STL (2)", when obtaining the data type referred to by the iterator, the template real-parameter inference mechanism is not used, instead, the built-in type technology and template special technology are used. The reason is that it cannot infer the type of the returned value. Here I will paste this code again.
// 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/>}
The iter_swap function uses the real parameter inference of the template to obtain the data type referred to by the iterator. But what if I want this function to return the data of the first iterator? The real parameter inference of the template is powerless. You can use the embedded type, as defined below. Note that the keyword typename must be added to indicate that the compiler is of a type. Otherwise, compilation fails.
# 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> // 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/> // exchange the elements referred to by the two iterators <br/> template <class Iter1, class Iter2> <br/> inline typename Iterator_traits <Iter1>: value_type // use an embedded type to obtain the type of the returned value <br/> iter_swap (Iter1 a, Iter2 B) {<br/> _ iter_swap (a, B, * a); // real parameter inference of the template <br/> return *; <br/>}</p> <p> int main () <br/>{< br/> list <int> l; <br/> l. push_back (3); <br/> l. push_back (4); <br/> cout <iter_swap (l. begin (), ++ l. begin () <endl; <br/> return 0; <br/>}
Reposted Source
Http://blog.csdn.net/wuzhekai1985