Implementation of templates in C + + (template classes and template functions)

Source: Internet
Author: User
Tags assert int size

[TOC]

Template

When we implement a swap function, we can write it as follows.

void Swap(int& x, int& y){    int tmp = x;    x = y;    y = tmp;}

Only two integers can be exchanged here, and when we need to implement a two-character exchange, we need to re-write a function, but two parts of the code have a lot of the same parts, which is not very troublesome. If we just need to write a code to achieve different types of exchange, is not very good. Yes, this compiler has been designed for us, which is called generic programming.
Template is the basis of generic programming, so-called generic programming is to write type-independent logic code, is a way to reuse.模板分为模板函数和模板类。

The format of template function template function:

template< class Parameter name 1, class parameter name 2, class parameter name n>
return type function name (parameter list)
{...}
 模板形参的定义既可以使用class,也可以使用typename,含义是相同的。
Just the swap function can be done with the template function.

Implicit instantiation of template parameters
template<class T>void Swap(T& x, T& y){    T tmp = x;    x = y;    y = tmp;}

See if you can do multiple types of switching, test results:

This is the implementation of the template function, of course, we are curious why a function can be done. In fact, at the bottom of the implementation of function overloading, we go to the assembly code to know.

int main () {00394d30 push ebp 00394D31 mov ebp,esp 00394d33 sub esp,114h 00394d39 push EBX 00394d3a push esi 00394d3b push EDI 00394d3c Lea edi,[ebp-114h] 00394D42 mov EC  x,45h 00394D47 mov eax,0cccccccch 00394d4c rep stos dword ptr Es:[edi] 00394d4e mov eax,dword ptr [__security_cookie (039a000h)] 00394d53 xor EAX,EBP 00394d55 mov dword ptr [EBP-4],EAX int a1 =         1, a2 = 2;00394d58 mov dword ptr [a1],1 00394d5f mov dword ptr [a2],2 Swap (a1, a2); 00394d66 Lea        EAX,[A2] 00394d69 push eax 00394d6a Lea ECX,[A1] 00394d6d push ecx 00394d6e Call  Swap<int> (039137Ah) 00394d73 add esp,8 char c1 = 5, C2 = 6;00394d76 mov byte ptr [c1],5 00394D7A mov byte ptr [c2],6 Swap (c1, C2); 00394d7e Lea EAX,[C2] 00394d81 push eax 00394D The ECX,[C1 Lea]  00394d85 push ecx 00394d86 call swap<char> (0391375h) 00394d8b add esp,8 double d1       = 1.222, D2 = 2.011111111111;00394d8e movsd xmm0,mmword ptr [[email protected] (0397bd0h)] 00394d96 movsd       Mmword ptr [d1],xmm0 00394d9b movsd xmm0,mmword ptr [[email protected] (0397bd8h)] 00394da3 movsd         Mmword ptr [d2],xmm0 Swap (D1, D2); 00394da8 Lea EAX,[D2] 00394DAB push eax 00394DAC Lea      ECX,[D1] 00394DAF push ecx 00394db0 call swap<double> (039137Fh) 00394DB5 add esp,8 Return 0;00394DB8 XOR Eax,eax}

You can see that at the bottom, each call to the SWAP function creates a stack frame, and each time the stack frame is set up, the type of the parameter is different, and the stack frame is created differently. When we use the template, the compiler makes a deductive process, which is done before compiling. When inferred, the compiler instantiates ( 编译器隐式实例化 ) based on the type of the passed parameter
Out the corresponding function, which is compiled. For example:

But when we run into Swap(1,1.2302102); This, how does the compiler determine what type of instantiation it is?
In fact, if we declare the template as this can be solved. 模板函数重载 (overloaded with the above function)

template<typename T1 ,class T2> //使用class 和 typename一样的效果void Swap(T1& x,T2& y){    T1 tmp = x;    x = y;    y = tmp;}

Sometimes we may have to go to such a wonderful problem.

template< class T>const T Add(T& x,T& y){    return x+y;}

When we call Add(1,5.222222); This, how does the compiler instantiate it?

Template parameter Display instantiation

this involves having to display the specified instantiation type模板参数显示实例化
Add &lt;double&gt; (1.5.2222222), so you can fix the problem just now.

Ii. format of template class template class
template<class 形参名1, class 形参名2, ...class 形参名n>class 类名{ ... };

When we first started to write sequential tables and linked lists in C + +, we did.

typedef int Datatype;typedef struct SeqList{    struct SeqList* _data;    size_t _size;}SeqList;typedef struct ListNode{    struct ListNode* _prev;    struct ListNode* _next;    Datatype _data;}ListNode;

We define the order table and the linked list in this way, but there is a big problem, as follows.

When we want to use two different data type sequential tables and linked lists in a program, this cannot be done unless we define a type for each of the types

typedef int DATATYPE; Save int Type

typedef struct SEQLIST
{
struct seqlist* _data;
size_t _size;
}seqlist;

typedef struct LISTNODE
{
struct ListNode _prev;
struct ListNode
_next;
Datatype _data;
}listnode;

typedef char Datatype; //存char类型typedef struct SeqList{    struct SeqList* _data;    size_t _size;}SeqList;typedef struct ListNode{    struct ListNode* _prev;    struct ListNode* _next;    Datatype _data;}ListNode;

It's going to be a hassle, and after we've learned the template, we can do that.

Template class Example

Template Implementation Order table

Template<class T>class vector{public:vector (): _first (null), _finish (null), _endofstorge (NULL)//constructor {} ~vect        or ()//destructor {Delete[]_first;    _first = _finish = _endofstorge = NULL;         } Vector (const vector<t>& v)//Copy construction: _first (NULL), _finish (null), _endofstorge (null) {        int len = V._finish-v._first;        _first = _finish = new T[len];        t* start = V._first;            while (start! = v._finish) {* (_finish) = *start;            ++_finish;        ++start;    } _endofstorge = _first+len;        } vector<t>& operator= (vector<t>& v)//assignment operator overload {Delete[]_first;        Vector<t> v1 (v);        Swap (_first, v1._first);        Swap (_finish, v1._finish);        Swap (_endofstorge, v1._endofstorge);    return *this;        } void Pushback (const t& x)//tail interpolation {if (_finish = = _endofstorge) Expand (Capacity () *2+1); _first[size ()] = x;    ++_finish;    } void Popback ()//tail Delete {Erase (Size ()-1);        } void Expand (size_t N)//capacity expansion {int size = size ();            if (n>capacity ()) {t* tmp = new T[n];            for (int i = 0;i<size;i++) {* (tmp+i) = * (_first+i);            } Delete[]_first;            _first = tmp;            _finish = _first + size;        _endofstorge = _first + N;        }} void Insert (size_t pos,const t& x)//random Insert {assert (_first+pos <= _finish);        if (_finish = = _endofstorge) Expand (2*capacity ());        t* end = _finish;            while (end! = _first + pos) {* (end) = * (end-1);        --end;        } _first[pos] = x;    ++_finish;        } void Erase (size_t pos)//delete data at any location {assert (_first+pos < _finish);        int size = size ();        t* start = _first + pos + 1; while (start! = _finish) {* (start-1) = * (start);        ++start;    }--_finish;        } size_t Find (const t& x)//Find {int size = size ();        for (int i = 0;i<size;i++) {if (_first[i] = = x) return i;    } return-1;        } t& operator[] (size_t POS)//Get data at any location {assert (Pos<size ());    return _first[pos];        } const t& operator[] (size_t pos) const {ASSERT (_first+pos < _finish);    return _first[pos];    } size_t Size ()//Fetch the valid capacity of the order table {return _finish-_first;    } size_t Capacity ()//Fetch the capacity of the sequential table {return _endofstorge-_first;    } bool Empty ()//Determine if the empty order table {return Size () ==0;    }protected:t* _first;    t* _finish; T* _endofstorge;};

Test code and results:

void VectorTest(){    Vector<int> v;    v.PushBack(1);    v.PushBack(2);    v.PushBack(3);    v.PushBack(4);    v.PushBack(5);    v.PushBack(6);    v.PushBack(7);    PrintVocter(v);    Vector<string> v1;    v1.PushBack("hello");    v1.PushBack("world !");    v1.PushBack("i");    v1.PushBack("love");    v1.PushBack("you");    PrintVocter(v1);}


Template implementation doubly linked list

#ifndef __list_h__#define __list_h__#include<string> #include <iostream>using namespace Std;template <    Class t>struct listnode{struct listnode* _prev;    struct listnode* _next; T _data;}; Template <class t>class list{typedef listnode<t> node;public:list ()//constructor {_head = new Node        ;    _head->_next = _head->_prev = _head;        } List (const list<t>& h)//copy construction {node* head = H._head;        node* tmp = head->_next;        _head = new Node;        _head->_next = _head->_prev = _head;            while (tmp! = head) {pushback (tmp->_data);        TMP = tmp->_next;        }} ~list ()//destructor {Clear ();        Delete _head;    _head = NULL;        } void Pushback (const t& x)//tail interpolation {node *tmp = new node;        Tmp->_data = x;        node* tail = _head->_prev;        Tail->_next = tmp;        Tmp->_prev = tail; _head->_prev = TMP    Tmp->_next = _head;        } void Pushfront (const t& x)//head interpolation {node *tmp = new node;        Tmp->_data = x;        node* cur = _head->_next;        Tmp->_prev = _head;        _head->_next = tmp;        Tmp->_next = cur;    Cur->_prev = tmp;        } void Popback ()//tail Delete {node* cur = _head->_prev;        _head->_prev = cur->_prev;        Cur->_prev->_next = _head;        Delete[]cur;    Cur->_next = Cur->_prev = NULL;        } void Popfront ()//header Delete {node* cur = _head->_next;        _head->_next = cur->_next;    Cur->_next->_prev = _head;        } void Insert (node* pos,const t& x)//random Insert {node* cur = new Node;        Cur->_data = x;        Cur->_prev = pos->_prev;        Pos->_prev->_next = cur;        Pos->_prev = cur;    Cur->_next = pos;        } void Erase (node* pos)//delete random position {node* cur = pos->_next; Pos->_prev-> _next = cur->_next;    Cur->_next->_prev = pos->_prev;        } void Clear ()//Clear list data {node* cur = _head->_next;            while (cur! = _head) {node* tmp = cur;            Cur = cur->_next;        Delete tmp;        } _head->_next = _head;    _head->_prev = _head;        } node* Find (const t& x)//Find {node* cur = _head->_next;            while (cur! = _head) {if (cur->_data==x) return cur;        Cur = cur->_next;    } return NULL;        } size_t Size ()//Fetch list Length {size_t count = 0;        node* cur = _head->_next;            while (cur! = _head) {count++;        Cur = cur->_next;    } return count;        } bool Empty () {if (_head->_next = _head->_prev) return 1;    return 0;        } void Printlist ()//Print List {node* TMP = _head->_next; while (tmp! = _head)       {std::cout<<tmp->_data<< "";        TMP = tmp->_next;    } std::cout<<std::endl; }protected:node* _head;}; #endif//__list_h__


This allows us to implement any type of program in our sequential tables and lists.

Implementation of templates in C + + (template classes and template functions)

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.