Simple introduction and use of templates

Source: Internet
Author: User
Tags types of functions

Simple introduction and use of templates

What is a template?

Template refers to the function templates and class templates in c ++, which correspond to the general concepts of C # and Java. Currently, templates have become an indispensable part of C ++ generic programming.

The template definition starts with the keyword template, followed by the template parameter table. The template parameter table is a list of one or more template parameters enclosed by Angle brackets. The parameters are separated by commas. A template parameter can be a type parameter or a non-type parameter that represents a constant expression. Non-type parameters are declared after the type specifiers. The type parameter is defined after the keyword class or typename. (the difference between class and typename is not big. in earlier versions of c ++, only class and typename are available. In most cases, the two are common, and typename must be used in only a few special cases. In short, using typename is foolproof. For the differences between the two, refer to this Article ).

The template is an excellent weapon for C ++ programmers, especially after combining multiple inheritance with operator overloading. The C ++ Standard Library provides many useful functions most of which are combined with the concept of templates, such as STL and IO Stream.

 

Function Template

The so-called function template is actually a general function. Its function type and parameter type are not specified, it is represented by a virtual type. This generic function is called a function template. Any function with the same function body can be replaced by this template without defining multiple functions, you only need to define it once in the template. When calling a function, the system replaces the virtual type in the template based on the type of the real parameter, thus implementing the functions of different functions 。

Most of the introductions on the internet start with comparing the two numbers. This article still describes how to compare them. Assume that one of the two numbers needs to be compared, but the types of the two numbers are uncertain, it may be int, float, or double type.

Of course, one way is to use function overloading, but the problem caused by using Overloading is: how many types of functions are likely to be written. Assume that only float and double types are required in the current requirement. However, if the int type is allowed one day, you need to add an overloaded function for the int type parameter in the code.

At this time, the function template will be used. You only need to define a function with generic parameters to compare multiple types of parameters. Let's look at the following code:

  

1 class MyTemplate 2 {3 public: 4 MyTemplate (void); 5 ~ MyTemplate (void ); 6 7 // start with a keyword template followed by <typename T> or <class T> the return value type and parameter type are both T 8 template <typename T> T Max (T, T B) 9 {10 return a> = B? A: B; 11}; 12 };

Here, T will be specially converted into the actual parameters passed in the Code call during program compilation, for example

To compare the values of two int types:

    MyTemplate mytemplate;    int x = 10;    int y = 100;    int val = mytemplate.Max(x,y);    

T in the program is replaced with int during compilation. The replaced program should look like the following:

  template <typename int> int Max(int a,int b)   {      return a>=b?a:b;  };

The float and double types are the same, so we won't repeat them here.

Class Template

When we have more complex requirements, for example, to implement a queue, there may be more than int data in this queue, there may also be string, double, or more complex custom types. For example, the following queue stores multiple data types of objects, and a class template needs to be defined.

Simple queue implemented by class templates

1 # pragma once 2 3 template <typename T> class FZQueue; 4 template <typename T> class queueItem 5 {6 private: 7 friend class FZQueue <T>; // because queueItem only needs to be called directly by FZQueue, it must be declared as a friend of FZQueue 8 9 queueItem (void) {}; 10 11 queueItem (const T & item1, const queueItem * p): item (item1), next (p) {}; 12 13 queueItem (const T & t): item (t), next (0 ){}; // explicitly define the copy constructor to set item to t next to NULL pointer 14 15 ~ QueueItem (void) {}; // destructor 16 17 T item; 18 19 queueItem * next; 20}; 21 22 template <typename T> 23 class FZQueue24 {25 public: 26 FZQueue (void): head (0), tail (0) {}; 27 ~ FZQueue (void) 28 {29 destroy (); 30 }; 31 32/* explicit replication constructor can be declared without explicit impact on this function */33 FZQueue (const FZQueue & t): head (0), tail (0) // copy the values of each element in t to the newly declared object. The pointer head and tail must be initialized. Otherwise, a memory access exception 34 {35 copy_elements (t) will be reported during the call ); 36}; 37 38 FZQueue & operator = (const FZQueue &); // explicit value assignment operator overload can be declared without explicit impact on this function 39 40 T & front () // get the queue header 41 {42 return head-> item; 43}; 44 45 46 void push (const T & item) // Add element to team end 47 {48 queueItem <T> * p_item = ne W queueItem <T> (item); 49 if (empty () 50 {51 head = tail = p_item; 52} 53 else54 {55 tail-> next = p_item; 56 tail = p_item; 57} 58}; 59 60 void pop () // Delete the queue Header element 61 {62 queueItem <T> * p_curHead = head; 63 head = head-> next; 64 delete p_curHead; 65}; 66 67 bool empty () // determine whether the queue is empty 68 {69 return head = 0; 70 }; 71 72 private: 73 queueItem <T> * head; // pointer to the queue Header element 74 75 queueItem <T> * tail; // pointer to the team end element 76 77 void destroy () 78 {79 while (! Empty () 80 {81 pop (); 82} 83}; 84 85 void copy_elements (const FZQueue & t) 86 {87 queueItem <T> * p = t. head; 88 // int I = 0; 89 while (p)/* I <5 */90 {91 push (p-> item ); 92 p = p-> next; 93 // I ++; 94} 95}; 96 97 };View Code

The call code is as follows:

1 if (valIndexs. empty () 2 {3 for (int zi = 10; zi! = 15; zi ++) 4 {5 valIndexs. push (zi); 6} 7} 8 FZQueue <int> clone_valZindexs (valIndexs); 9 10 cout <"valIndexs:" <valIndexs. front () <"______ clone_valZindexs:" <clone_valZindexs.front () <endl; 11 12 cout <"valIndexs:" <valIndexs. front () <"______ clone_valZindexs:" <clone_valZindexs.front () <endl;View Code

The above is the complete code for implementing simple queues using a class template.

Problem and summary

1. after removing the constructor overload (FZQueue (const T & t);) and operator overload (FZQueue & operator = (const FZQueue &);) in the class, they all run normally, I don't know under what circumstances this constructor overload and operator overload will be used.

Conclusion: refer to the copy constructor section in copy control in Chapter 4 of C ++ Primer. The description of the copy constructor is as follows:

A copy constructor is a special constructor with a single parameter. This parameter (commonly used for const modification) is a reference to this type. When you define a new object and initialize it with an object of the same type, the copy constructor is explicitly used. When you pass an object of this type to a function or return an object of this type from a function, the copy constructor is implicitly used. Can be used for: 1. an object is displayed or implicitly initialized based on another object of the same type. copy an object and pass it as a real parameter to a function 3. copy an object when the function returns 4. initialize elements in the sequential container 5. initialize array elements based on the element initialization list

Moreover, if the definition is not displayed in the program and the replication constructor is implemented, the compiler automatically generates the constructor. The assignment operator overload and destructor are the same.

The custom class cannot be declared as a pointer, for example, FZQueue <int> * clone_zindexs. If this is done, the pointer will be used when the parameter calls the copy constructor, the replication constructor does not work because a pointer is declared here.

 

 

Related Article

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.