The Gospel of "lazy man"---generic programming

Source: Internet
Author: User

Lazy steps to take the stairs, so there is an elevator, too lazy to walk, so they create cars, trains, airplanes, too lazy to calculate, so found a calculator; lazy to repeat the code, so there is a generic programming in C + +!

Of course, the above paragraph is my nonsense, the real situation may be completely different, but it can also be a good way to elicit the content today---C + + generic programming. Other words also don't say more, start to get to the point! Today, the main analysis in the generic programming: 1, template functions & Template parameters & Function overloading 2, template class 3, template special concept, and finally say that the template separation of the compilation.

In the absence of learning generic programming or the concept of a template, if someone asked you to write a general formula, such as allowing you to implement a generic addition function, what would you write about? Usually we have the following workarounds:

The first is the easiest way to use function overloading when you are not learning generic programming .

int Add (const int &_ileft, const int &_iright)             //Reshape addition {    return (_ileft + _iright);} float Add (const float &_fleft, const float &_fright)       //floating-point type addition {    return (_fleft + _fright);}
Although this method is easy to think of, it is not difficult to achieve, but there are also a large defect, in my opinion, it has the following four shortcomings (of course, there are many drawbacks) disadvantage one : As long as there is a new type, it is necessary to re-add the corresponding function , too cumbersome. disadvantage two : The code has a low reusability rate . disadvantage three : If the function is only the return value type , the function overload cannot be resolved (the condition of the function Overload: the same scope, the same function name, the parameter list is different). Disadvantage four: A method has a problem, all the methods have problems, not good maintenance .

Since the first method is not good, let's take a look at the second method, using the common base class, put the common code in the common base class , this method is easy to understand, here does not give an example, it is worth mentioning that this method also has shortcomings. First: By using common base classes to write generic code, you lose the benefits of type checking, and second: For many classes that are implemented later, you must inherit from a particular base class, and code maintenance is more difficult .

another way is to use a special preprocessing program, such as:

#define ADD (A, B) ((a) + (b))

However, this method is too restrictive, and we do not advocate the use of macro substitution, the macro itself has a lot of shortcomings, although it seems simple and clear, but it does not do parameter type detection, it is not easy to maintain, security is not high , in short, in C + + When you can not use the macro as far as possible, it is best to use the const or the inline keyword to play the effect of the macro.

Based on the above limitations or shortcomings, generics programming in C + + has emerged. What is generic programming? Let's start by understanding what generic programming is, and simply summarize: writing type-independent logic code is a means of code reuse. In other words, generic programming is to write code in a way that is independent of any particular type, whereas a template is the basis for generic programming. There is also a concept template, what is a template? Let's take a look at the picture:


function Templates

Let's start with an analysis, first of all a function template, what is a function template? Function Template: represents a function family, which is independent of the type, is parameterized when used, and produces a specific type version of the function based on the argument type . Since a function template is a type-independent function that can produce something of a specific type version of a function, how does it work?

First, let's look at the format of the function template:

Template<typename Param1, TypeName Param2,..., class paramn>//return value type function name (parameter list) {...}

Of course, in the processing of the format, there are a few things to say:

TypeName is used to define template parameter keywords, or you can use class. However, we recommend using TypeName as much as possible. Note: You cannot use structs instead of TypeName.

Also worth mentioning is that the template function can be defined as an inline function

Template<typename t>inline T My_add (const T _left, const T _right) {return (_left + _right);}
Note: Theinline keyword must be placed after the template parameter list, and before the value is returned, it cannot be placed before the stencil .

Having finished the format, naturally we need to use examples to illustrate briefly:


Above is an example of simply using the function template to do the addition operation, a total of 4 output content, the front two no problem. But here is the concept of an actual argument deduction .

argument deduction : The process of determining the type and value of a template parameter from a function argument is called template argument inference, but it is important to note that if there are multiple arguments, the arguments of multiple type parameters must match exactly . Otherwise, the compilation will go wrong.

The third output statement if there is no (int) in front of 34.12, the result is: you pass two different type parameters to the function template, but the function template cannot determine the type of the template parameter T , so compile an error.

But why was there an error during compilation ? In other words, what exactly did the function template do during compilation? In fact, the compilation of the function template can be divided into two processes (it can also be thought that the template was compiled two times):

For the first time before instantiating, check the template code itself to see if there is a syntax error, but simply check, for example: missing semicolon.
The second time during instantiation, check the template code to see if all calls are valid, such as: The instantiated type does not support some function calls.

(again, the concept of instantiation, the template is a blueprint, it is not a class or function, compiler with a template to produce a specific type of class or function version, the process of producing template-specific type is called function template instantiation )

If we add a function above the main function at this time:

int Add (int left, int. right)  {       return left + right;  }  int main () {   ...   .. Cout<<add (1.2,2.5) <<endl;   return;}

So at this point we 'll think about which function the compiler will call, is it a generic type conversion to call the Add function we defined later, or does it call a function template to produce a new function? Will the type parameter conversion be done here?

        , but instead produces a new instance. The
        compiler will only perform :
         1, const conversion : A function that receives a const reference or a const pointer can call
        2, array or function-to-pointer conversion : If the template parameter is not a reference type, a regular pointer conversion is applied to an argument of the type of the group or function. An array real arguments as a pointer to its first element, and a function argument as a pointer to a function type.

so the above question is easy to answer, the compiler does not convert 1.2 and 2.5 to int , and thus calls the existing add version, but instead synthesizes a double version, of course, if you can generate such a template function. If this template function cannot be generated, then only the existing version can be called.

Now let's look at the concept of template parameters :

A function template has two types of parameters: a template parameter and a call parameter, and the template parameter can be split in the same way:


For template parameters, there are the following areas to note:

1. template parameter names can only be used after template parameters to the end of a template declaration or definition , following the name masking rule.

2. The name of the template parameter can only be used once in the same template parameter list

3. All template parameters must be preceded by a class or typename keyword decoration (note: You cannot specify a default template argument inside a function template)

Then say the concept of non-template type parameters .

What are non-template type parameters? non-template type parameters are constants defined inside the template , and non-template type arguments can be used when constant expressions are required. For example, we can specify the length of the array as a non-template type parameter, and take a look at the following picture:


In many cases we will encounter the concept of type equivalence, what is type equivalence?

const int ibytecnt = 9;int B[ibytecnt+1];int a[10]; Funtest (a); Funtest<int, 10> two arrays equivalent funtest (b); Funtest<int, the 10> compiler does not synthesize new functions
here is a summary of the template parameters :

1. The template parameter list is used <> enclosed
2, like the function parameter table, with multiple parameters must be separated by commas , the type can be the same or different
3. The template parameter list cannot be empty
4, template parameters can be type parameters, or non-type new parameters, type parameters after class and TypeName
5. Template type parameter can be used as type description trailing characters anywhere in the template, using the same methods as built-in or custom types to specify function parameter types, return values, local variables, and coercion type conversions
6, the template parameter list,class and TypeName have the same meaning, can be interchangeable , using typename more intuitive. However, the keyword TypeName is added to C + + as a C + + standard, which may not be supported by the old compiler.

Next is the template function overload , here I steal a lazy, refer to the information on the Internet:

int Max (const int& left, const int & right) {   return left>right? Left:right;} Template<typename t>t Max (const t& left, const t& right) {   return left>right? Left:right;} Template<typename t>t Max (const t& A, const t& B, const t& c) {   return Max (Max (A, B), c);}; int main () {   Max (ten, +);                      Max<> (ten);                  The equivalent of telling the compiler that you need to use a template instead of calling the first function   Max (ten);   Max (ten, 20.12);                 An implicit type conversion occurs, so the first function   max<int> (10.0, 20.0) is called;   Max (10.0, 20.0);   return 0;}
It is important to note that all overloaded versions of a function's declarations should precede the function's called location.

Also make a summary:

1. A non-template function can exist with a function template of the same name , and the function template can also be instantiated as a non-template function.
2. For non-template functions and function templates with the same name, if other conditions are the same, the non-template function will be transferred instead of generating an instance from the template when the transfer takes precedence. if a template can produce a function that has a better match,
Then the template will be selected .
3. Explicitly specify an empty template argument list, which tells the compiler that only the template can match the call , and that all template parameters should be interpreted according to the arguments.
4, the template function does not allow automatic type conversion, but the normal function can be automatic type conversion .

Finally, to understand the template function of the special

Sometimes it is not always possible to write a template that is most appropriate for all types that might be instantiated, and in some cases the generic template definition may be completely wrong for a type, or not compile, or do something wrong.

You can define this as follows.


The template functions are in the following form:
1. Keyword template followed by an empty pair of angle brackets <>
2, followed by the template name and a pair of angle brackets, the angle brackets specify the template parameter of this special definition
3. Function formal parameter list
4. Function body

Template<> return value function name <Type> (parameter list) {    //function Body}
However, you need to be aware of the following:

The following two points also need to be noted: 1, in the template-specific version of the call, the argument type must match the formal parameter type of the special version function exactly , if not, the compiler will instantiate an instance for the argument template definition. 2. After a call to the template instance, the special can not appear in the header file, you should include the template-specific declaration, and then use the specific version of each source file contains the header file.

template class

go to our template class and take a look at how to use the template class (with the order table as an example):

Normal order table:

typedef int DATATYPE;//TYPEDEF Char Datatype;class seqlist{     private:     datatype* _data;     int _size;     int _capacity;};
Template class Order table:

Template<typename T>class seqlist{    private:    t* _data;    int _size;    int _capacity;};
because the template class is also a template, you must start with the keyword template, followed by the template parameter list.

Therefore, the general format of the template class can be summed up:

Template<class parameter name 1, class parameter Name 2, ... class parameter name N>class category name {...};
after looking at the following picture, you can understand the template class in a preliminary way:


Instantiation of the template class
As long as there is a different type, the compiler instantiates a corresponding class .

Seqlist<int > SL1; seqlist<double > SL2;
When defining these two types of sequential tables, the compiler uses int and double instead of the template parameters, rewriting the Seqlist class, and finally creating a class named Seqlist<int> and Seqlist<double>.

In fact, here can lead to a concept about the adapter, interested can go to understand.

separation and compilation of templates

Generally speaking, the class template can not be separated from the compilation, the reason is to start with the instantiation of the templates.

1) in a separate form of the template class (in tem.h and tem.cpp for example, as well as the main function main.cpp), when compiling the main.cpp because only the template declaration can not see the implementation, so the new type will not be created, but there is no error, because the compiler believes that the template definition in other files, the problem is left to the chain Handler.

2) When compiling tem.cpp, the compiler can parse the template definition and examine the syntax, but not the code that generates the member function. Because you want to generate code, you need to know the template parameters, that is, a type, not the template itself.

3) In this way, the linker cannot find the definition of the new type in either Main.cpp or tem.cpp, so it reports an error with no defined member. In addition, instantiation is lazy, and only the function is used to instantiate the definition in the template.

Therefore, the template during the separation of the compilation process will occur link error , usually prompt unresolved external commands, there are the following two solutions:

1. In the template header file xxx.h, display the definition of the template class, add the name < type >; This method is generally not recommended, on the one hand, the old compiler may not support, on the other hand instantiation of the dependent callers. (Not recommended)
2. It is recommended to put the declaration and definition in a file "Xxx.hpp".

If you are interested in detaching the template, Portal: http://blog.csdn.net/pongba/article/details/19130

Finally summarize the template
Advantages
Template Reuse code , save resources, faster iterative development, C + + Standard Template Library (STL) resulting.
Increases the flexibility of the code.
Disadvantages
Templates make code messy, difficult to maintain , and time-coded to grow.
When a template compilation error occurs, the error message is very messy and difficult to locate errors .



The Gospel of "lazy man"---generic programming

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.