C ++ Primer study note _ 75 _ templates and generic programming

Source: Internet
Author: User

Template and generic programming-template Definition



Introduction:

Generic programs write code independently of any specific type. When using a generic program, we need to provide the type or value operated by the specific program instance.

TemplateIs the basis of generic programming.You do not need to understand the template definition when using the template..

Generic programming, like object-oriented programming, relies onSome form of Polymorphism. OrientedObject programmingThe polymorphism in is applied to classes with inheritance relationships at runtime. We can write code that uses these classes,Ignore the type differences between the base class and the derived class. The same Code can be used for objects of the base class or derived class type as long as the base class reference or pointer is used.

In generic programming, the classes and functions we write can be used for PolymorphismNon-relevant types during compilation. A class or function can be used to manipulateMultiple typesOfObject. Containers, iterators, and algorithms in the standard library are examples of good generic programming. The standard library defines each container, iterator, and algorithm in a type-independent manner. ThereforeClasses and functions of the standard library can be used for almost any type.

In C ++, templates are the basis of generic programming. Template is createdClass or function.



Compile overload functions:

int compare(const string &v1,const string &v2){    if (v1 < v2)    {        return -1;    }    else if (v1 > v2)    {        return 1;    }    return 0;}int compare(const double &v1,const double &v2){    if (v1 < v2)    {        return -1;    }    else if (v1 > v2)    {        return 1;    }    return 0;}

These functions are almost the same.Unique differenceIs the type of the parameter,The function bodies of each function are the same..

Every type that needs to be compared must repeat the function body, which is not only troublesome but also prone to errors. More importantly, you need to know in advance what types of space may be compared. If you wantUse functions for unknown types,This policy does not work anymore..



1. Define a function Template

Instead of defining a new function for each type, we can define a function template. A function template is a type-independent function that can be used as a method to generate a specific function version.

template<typename T>int compare(const T &v1,const T &v2){    if (v1 < v2)    {        return -1;    }    else if (v1 > v2)    {        return 1;    }    return 0;}

Template definition with keywordsTemplateStart, followedTemplate parametersThe template parameters table is a list of one or more template parameters enclosed by Angle brackets. The parameters are separated by commas. The template parameter table cannot be empty.



1. template parameters

Template parametersSimilar to a function parameter table, it indicates the type or value that can be used in the definition of a class or function. For example, the compare function declares a type parameter named T. Within compare, you can use name T to reference a type,TIndicates which actual typeCompilerAccordingFunctions usedAnd OK.

The template parameter can be a type parameter or a type parameter.Constant expression. Type parameters and keywordsClassOrTypenameAnd then define.



2. Use the function Template

When using a function template, the compiler determines which (OR)Template parametersBindTemplate parameters. Once the compiler determines the actual template arguments, it is calledInstantiationAn instance of the function template.

After the actual template parameters are exported, the compiler uses the real parameters.ReplaceThe corresponding template parameters generate the function for compiling this version.

Int main () {// bind to compare (const int &, const int &) cout <compare (1, 0) <endl; // bind to compare (const string &, const string &) string s1 = "hi", s2 = "world"; cout <compare (s1, s2) <endl; return 0 ;}

3. inline function Template

The inline specifier is placed after the template parameter table and before the return type. It cannot be placed before the keyword template.

template<typename T> inlineint compare(const T &v1,const T &v2);//OKinline template<typename T>int compare(const T &v1,const T &v2);//Error

// P528 exercise 16.1 template <typename T> inlineT abs (T val) {return val> 0? Val:-val;} int main () {cout <abs (-1) <endl; cout <abs (-0.98) <endl; cout <abs (short (3.4) <endl; return 0 ;}

// Exercise 16.2 template <typename T> ostream & write (ostream & OS, T val) {return OS <val <endl ;}int main () {write (cout, 1); write (cout, 12.3); write (cout, "Hello World"); ofstream outFile ("output"); write (outFile, "Hello "); write (outFile, 123); string temp; ostringstream strStream (temp); write (strStream, "Hello_World"); cout <strStream. str () <endl ;}


Ii. Define a class template

To illustrate the class template, we will implement our own version for the standard library queue class.

The custom Queue class must support different types of objects, so it is defined as a class template. Operations supported by Queue:

1) push: add an item at the end of the team

2) pop: delete an item from the queue Header

3) front: return the reference of the Team header.

4) empty: indicates whether the queue is empty.

template<typename Type> class Queue{public:    Type &front();    const Type &front() const;    void push(const Type &);    void pop();    bool empty() const;private:    //...};

The class template is also a template, so you must use a keywordTemplateStart with, followed by the template parameter table.

In addition to the template parameter table,The class template definition looks similar to any other class. In the definition of classes and class members, you can use template parameters as placeholders of types or values, and provide those types or values when using classes.



Use a class template

Compared with calling a function template, when using a class template, it must beTemplate parametersExplicitly specifyReal Parameters:

    Queue<int> qi;    Queue< vector<double> > qc;    Queue<string> qs;

The compiler uses real parameters to instantiate a specific version of the class. In essence, the compiler replaces Type with the actual Type provided by the user,RewriteQueueClass. In this example, the compilerInstantiate threeQueueClass: The first one uses int instead of Type, the second one uses vector <double> instead of Type, and the third one uses string instead of Type.

// P529 exercise 16.5 template <typename T> T getBigger (const T & val1, const T & val2) {return val1> val2? Val1: val2 ;}

// Exercise 16.6 template <typename Type> class List {public: List (); void push_back (const Type &); void push_front (const Type &); std :: size_t size () const; void insert (Type * ptr, const Type & val); bool empty (); private ://...};

Iii. template parameters

Like a function parameter, the name selected for the template parameter has no essential meaning:

template<typename Glorp>int compare(const Glorp &v1,const Glorp &v2){    if (v1 < v2)    {        return -1;    }    else if (v1 > v2)    {        return 1;    }    return 0;}

The Code is the same as the compare template defined earlier.

The only meaning that a template parameter can be granted isThe difference is thatType parameterOrNon-type parameters. If it is a type parameter, we know that this parameter represents an unknown type. If it is a non-type parameter, we know that it is an unknown value.

If you want to use the type or value represented by the template parameters, you can use the same name as the corresponding template parameters. For example, all Glorp references in the compare function are determined to be of the same type when the function is instantiated.



1. Scope of template parameters

The name of the template parameter can be declared as the template parameterTemplate declarationOrAt the end of the definition.

The template parameters follow the regular name blocking rules:

Typedef double T; template <class T> T calc (const T & a, const T & B) {// here T is T in the template parameter table, the global name is blocked T tmp = ;//... return tmp ;}

2. Restrictions on using template parameters

The name used as the template parameter cannot be reused within the template:

template <class T>T calc(const T &a,const T &b){    typedef double T;   //Error    T tmp = a;    //...    return tmp;}

This restriction also means that the name of the template parameter can only beThe same template is used once in the form parameter table:

template <class T,class T> T calc(const T &a,const T &b);//Error

Just as you can reuse the name of a function parameter, the name of the template parameter can also be reused in different templates:

template <class T> T calc(const T &a,const T &b);template <class T> int compare(const T &,const T&);//OK

3. template declaration

Like any other function or classTemplateYesDeclare only, not define.The declaration must indicate that a function or class is a template.:

template <class T>int compare(const T &,const T&);

In the Declaration and definition of the same template, the template parameters must be named differently:

template <class T>T calc(const T &,const T &);template <typename U>U calc(const U&,const U&);template <class Type>Type calc(const Type &,const Type &);

The class or typename keyword must be included before each template type parameter, and the type name must be included before each non-type parameter. The keyword or type specifier omitted is incorrect:

template<typename T,U>T calc(const T &,const U &);//Errortemplate<typename T,class U>T calc(const T &,const U &);//OK

// P531 exercise 16.9 template <typename Type, typename T> Type find (Type begin, Type end, const T & val) {while (begin! = End) {if (* begin = val) {return begin;} + + begin;} return end;} int main () {int ia [] = {01,1, 1,999, 4}; int * p; if (p = find (ia, ia + sizeof (ia)/sizeof (* ia ), 999 ))! = Ia + sizeof (ia)/sizeof (* ia) {cout <* p <endl;} else {cout <"Not Found! "<Endl ;}vector <int> iVec (ia, ia + sizeof (ia)/sizeof (* ia); vector <int >:: iterator iter; if (iter = find (iVec. begin (), iVec. end (), 888 ))! = IVec. end () {cout <* iter <endl;} else {cout <"Not Found! "<Endl;} ifstream inFile (" input "); vector <string> strVec; string val; while (inFile> val) {strVec. push_back (val);} vector <string>: iterator it; if (it = find (strVec. begin (), strVec. end (), "hello "))! = StrVec. end () {cout <* it <endl;} else {cout <"Not Found! "<Endl ;}}

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.