In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly shows you the "sample Analysis of C++ template programming", which is simple and clear. I hope it can help you solve your doubts. Now let the editor lead you to study and learn the "sample Analysis of C++ template programming" this article.
Template initial generic programming
In the field of computer programming, in order to avoid being forced to write a large number of codes with the same business logic because of different data types, generics and generic programming techniques have been developed. What is generics? In essence, it does not use specific data types (such as int, double, float, etc.), but uses a general type to program design, this method can reduce the amount of program code writing on a large scale, so that programmers can focus on the implementation of business logic. Generics are also a data type, except that it is a "common type" that replaces all types.
How do we usually implement a general exchange function?
Void Swap (int& left, int& right) {int temp = left; left = right; right = temp;} void Swap (double& left, double& right) {double temp = left; left = right; right = temp;} void Swap (char& left, char& right) {char temp = left; left = right; right = temp;}.
The Swap function can exchange variables of various types, but you need to rewrite one as long as the type is different.
Although it is possible to use function overloading, there are several disadvantages:
The overloaded function is only of different types, and the reuse rate of the code is relatively low. as long as a new type appears, it is necessary to add the corresponding function.
The maintainability of the code is relatively low, one error may cause all overloads to go wrong, can you tell the compiler a template so that the compiler can use the template to generate code according to different types?
Yes, there are templates in C++ grammar:
Function template concept
The so-called function template is actually the establishment of a general function, and the types of data it uses (including return value types, formal parameter types, and local variable types) can be unspecified. Instead, it is replaced by a virtual type (actually using an identifier to occupy space), and then the real type is inversely deduced according to the passed arguments when the function call occurs. This generic function is called a function template (Function Template). The function template represents a family of functions that are type-independent and are parameterized when used to produce a specific type version of the function based on the argument type.
Function template format
Template
Return value type function name (parameter list) {}
Template// or templatevoid Swap (T & x1, T & x2) {T temp = left; left = right; right = temp;}
What is the type of T _ 1, T _ 1, T _ 2, etc. We are not sure now, but we can only determine when we use it later.
Note:
Typename is used to define the template parameter keyword, or you can use class
The principle of function template
The function template itself is not a function, but a mold for the compiler to generate a specific type of function according to the type of parameter called, so in fact, the template gives the compiler what we are supposed to do. Let's take a look at the following example:
Templatevoid Swap (T & x, T & y) {T temp = x; x = y; y = temp;} int main () {int a = 1; int b = 2; Swap (a, b); char A = 'a'; char B =' baked; Swap (AMague B); return 0;}
In the compiler compilation phase, for the use of template functions, the compiler needs to deduce the function that generates the corresponding type according to the passed argument type for calling. For example, when using a function template with the int type, the compiler determines T as the int type by deducing the argument type, but
The result is a piece of code that specifically deals with int types, as well as for character types.
However, when we write a function, we will not enter the template function. When we do not write a specific function, we will enter the template function. Let's take a look at the following example:
Void Swap (int& x, int& y) {int temp = x; x = y; y = temp;} templatevoid Swap (T & x, T & y) {T temp = x; x = y; y = temp;} int main () {int a = 1; int b = 2; Swap (a, b); char A = 'a'; char B =' b' Swap (A Magi B); return 0;}
Let's do the mode:
We can see that we wrote the swap function of the int type, and we wrote the call, but we used the template without writing the char type.
So is the template function called here?
No, actually, there are two processes here.
1. Template deduction, what is the specific type of T
2. Derive the specific type of T and instantiate it to generate a specific function.
The above code instantiates the following function:
Void Swap (char& x, char& y) {char temp = x; x = y; y = temp;}
What is really called are two functions, but one of them is not written by us, but we give the compiler a template, and then the compiler deduces that the template is instantiated to generate three corresponding functions before compilation. The compiler acts as a tool for writing functions:
You can see that the Swap function is called here.
In C++, built-in types can also be initialized in the same way as custom types:
Int a (1); int (2); / / Anonymous
Void Swap (T & x1, T & x2) {T temp (x1); x1 = x2; x2 = x1;}
So the template can also be written like this to make built-in types compatible with custom types:
Void Swap (T & x1, T & x2) {T temp (x1); x1 = x2; x2 = x1;}
Let's take a specific look at the instantiation of the function template:
Instantiation of function template
When a function template is used with different types of parameters, it is called the instantiation of a function template. Template parameter instantiation is divided into implicit instantiation and explicit instantiation.
Implicit instantiation: lets the compiler deduce the actual type of template parameters based on arguments
TemplateT Add (const T & left, const T & right) {return left + right;} int main () {int A1 = 10, a2 = 20; double D1 = 10.0, D2 = 20.0; Add (A1, a2); Add (D1, D2); / / there are two processing methods: 1. Users themselves to force the conversion of 2. Use explicit instantiation of Add (A1, D2); return 0;}
This statement cannot be compiled, because during compilation, when the compiler sees the instantiation, using A1 to push T is int, while using D2 to push is double, but there is only one T in the template parameter list, and the compiler is not clear whether the T is int or double,T, so the compiler will report an error.
So how to deal with it?
Solution:
1. The caller forces the conversion by himself.
/ / argument to deduce the type of formal parameter Add (A1, (int) D2); Add ((double) A1 Magi D2)
Here, you can cast d2 first and then deduce it, or A1 can cast it first and then deduce it.
2. Use explicit instantiation
/ / argument does not need to deduce the type of formal parameter. Explicitly instantiate the type of specified T, Add (A1 Magi D2); Add (A1 Magi D2)
This way is to explicitly instantiate the type of the specified T
In which scenario is explicit instantiation available? Look at the following scenario:
Class A {A (int aq0): _ a (a) {} private: int _ a;}; templateT func (int x) {T a (x); return a;} int main () {func (1); func (2); return 0;}
In some function templates, template parameters are not used in the parameters, so the template parameters are useful in the function body. At this time, the type of T cannot be deduced through the parameters, and instantiation can only be displayed.
We mentioned the matching principle of template parameters above. Let's take a look at the matching principle of template parameters:
Matching principle of template parameters
A non-template function can exist with a function template of the same name. If the calling local parameter matches exactly the non-template function, the non-template function will be called.
Int Add (int left, int right) {return left + right;} / / General addition function templateT Add (T left, T right) {return left + right;} int main () {Add (1) 2); / / call your own function return 0;}
The Add parameter is of type int, and we have a ready-made Add function for the int parameter, so if we have something ready-made, the compiler will be lazy
So what if we want the call here to have to use a template? Explicit instantiation:
Add (1 dint 2)
This forces the compiler to use a template to de-instantiate the function
A non-template function can exist with a function template of the same name. If the local parameter of the call does not exactly match the non-template function, the template instantiation function will be preferred.
Int Add (int left, int right) {return left + right;} / / General addition function templateT Add (T left, T right) {return left + right;} int main () {Add (1.1) 2.2); / / instantiate the function return 0;} using templates
Summary of template matching principles:
If there is a ready-made exact match, then directly call, there is no ready-made call, instantiation template generation, if there is a function that needs to be converted to match (that is, not exactly matching), then it will give priority to de-instantiation template generation.
Priority:
Exact match > template > Transformation Type matching
Definition format of class template templateclass class template name {/ / member definition within class}
Let's take a look at a scenario where a class template is used:
Typedef int STDateType;class Stack {private: STDateType* _ a; int _ top; int _ capacity;}; int main () {Stack st1; Stack st2; return 0;}
This is the stack data structure we defined. We created two stack objects, but now both st1 and st2 store data of type int. What if you want to convert the data type?
Typedef double STDateType
We change it this way, but what if we want st1 to be int,st2 and double:
Stack st1;//intStack st2;//double
At this point, you need to write multiple classes with different names, as follows:
Typedef int STDateType1;typedef double STDateType2;class IntStack {private: STDateType1* _ a; int _ top; int _ capacity;}; class DoubleStack {private: STDateType2* _ a; int _ top; int _ capacity;}
This is too troublesome, so what can be done to solve it? Class templates can solve the problem:
/ / Class template templateclass Stack {private: T* _ a; int _ top; int _ capaticy;}; int main () {/ / the use of class template is explicit instantiation Stack st1; Stack st2; return 0;}
Note: Stack is not a concrete class, but a mold for the compiler to generate concrete classes based on the instantiated type.
Instantiation of class template / / Class template templateclass Stack {public: Stack (int capacity = 4): _ a (new T (capacity)), _ top (0), _ capacity (capacity) {} ~ Stack () {delete [] _ a; _ a = nullptr; _ top = _ capacity = 0 } void Push (const Tx) {/ /...} private: T* _ a; int _ top; int _ capaticy;}; int main () {/ / the use of class templates is to explicitly instantiate Stack st1; Stack st2; return 0;}
Note: the use of class templates is explicitly instantiated
Suppose we want to declare inside the class and define member functions outside the class?
/ / Class template templateclass Stack {public: Stack (int capacity = 4): _ a (new T (capacity)), _ top (0), _ capacity (capacity) {} ~ Stack () {delete [] _ a; _ a = nullptr; _ top = _ capacity = 0;} / / suppose we want to separate the declaration and definition in the class? Void Push (const T & x); private: T* _ a; int _ top; int _ capaticy;}; / / define templatevoid Stack::Push (const T & x) outside the class; {/...} int main () {/ / the use of class templates is to explicitly instantiate Stack st1; Stack st2; return 0;} / / define templatevoid Stack::Push (const T & x) outside the class; {/ /.}
Define the keywords outside the class that we must add the template, and the domain Stack that needs to be indicated before the implemented function. For an ordinary class, the class name is the type. For the class template, the class name is not the type, and the type is Stack, which needs to be specified.
Note:
The template does not support writing the declaration to .h and the definition to .cpp. If the declaration and definition are implemented separately, there will be link errors.
The above is all the content of this article "sample Analysis of C++ template programming". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.