[Disclaimer: All Rights Reserved. You are welcome to reprint it. Do not use it for commercial purposes. Contact Email: feixiaoxing @ 163.com]
Recursion: I believe all the friends who have experience in basic C language know that the function calls itself. Therefore, essentially, it is no different from a common function call. Today, we associate template classes with recursion because we can use recursive methods to implement template recursion. Let's start with a statistical function.
Int process (int m)
{
Int index = 0;
Int count = 0;
Assert (m> = 0 );
For (; index <= m; index ++ ){
Count + = index;
}
Return count;
}
Int process (int m)
{
Int index = 0;
Int count = 0;
Assert (m> = 0 );
For (; index <= m; index ++ ){
Count + = index;
}
Return count;
}
The above code is not difficult. You can see that it is actually a computing function that calculates from 0 ~ The sum of m increments. So how should we write such a piece of code with recursion? You can try it on your own. The following code is my own solution for your reference.
Int process (int m)
{
Assert (m> = 0 );
If (m = 0)
Return 0;
Else
Return process (m-1) + m;
}
Int process (int m)
{
Assert (m> = 0 );
If (m = 0)
Return 0;
Else
Return process (m-1) + m;
} We can see that the purpose of recursion is to split the large computation into small computation, and then merge the computation. For example, if we calculate process (5), we need to calculate process (4); process (4) and process (3); process (3) also, process (2) needs to be calculated; process (2) has a need to calculate process (1); process (1) has a need to calculate process (0); process (0) the result is obtained. The value is 0, and process (1) can be obtained, and so on. Finally, the value of process (5) can be obtained. This is the whole process of recursive processing.
So what is the relationship between this and the template class? Let's take a look at the following example:
Template <int m>
Class calculate
{
Public:
Static int process ()
{
Return calculate <M-1 >:: process () + m;
}
};
Template <>
Class calculate <0>
{
Public:
Static int process ()
{
Return 0;
}
};
Template <int m>
Class calculate
{
Public:
Static int process ()
{
Return calculate <M-1 >:: process () + m;
}
};
Template <>
Class calculate <0>
{
Public:
Static int process ()
{
Return 0;
}
};
The above code is very interesting. We found that the data type of the template is no longer int, double, or custom data type, but a specific number. However, each number also represents a type. Therefore, calculate <5> and calculate <4> are two different classes. In addition, we also use static processing functions. However, the static functions here are a little special. We found that the static function process needs to call another static function of the class, that is, the static function of calculate M-1> to obtain the result. Therefore, to obtain the results, we need to create many classes and many static functions. So when will the class end? We can see that there is another class under calculate, that is, the special template of calculate. That is to say, when m = 0, it will not continue to be processed down, and the computation starts to return. So how can this class be applied? Let's take a look:
258: int value = calculate <5 >:: process ();
004013D8 call @ ILT + 45 (calculate <5 >:: process) (00401032)
004013DD mov dword ptr [ebp-4], eax
259: return;
260 :}
258: int value = calculate <5 >:: process ();
004013D8 call @ ILT + 45 (calculate <5 >:: process) (00401032)
004013DD mov dword ptr [ebp-4], eax
259: return;
260 :}
The above is the code for calling the Extended Assembly. There is no difference between Assembly and general function calls. Let's take a look:
242: return calculate <M-1 >:: process () + m;
00401F68 call @ ILT + 40 (calculate <4 >:: process) (0040102d)
00401F6D add eax, 5
243 :}
242: return calculate <M-1 >:: process () + m;
00401F68 call @ ILT + 40 (calculate <4 >:: process) (0040102d)
00401F6D add eax, 5
243 :}
The above Code omitted the intermediate jump. We found that the Code continues to call the static processing function of calculate <4>. Of course, this call will continue. So when will it end? Yes. The static calculate <1> function mentioned above is the special function. Let's take a look at it:
250: static int process ()
251 :{
00402090 push ebp
00402091 mov ebp, esp
00402093 sub esp, 40 h
00402096 push ebx
00402097 push esi
00402098 push edi
00402099 lea edi, [ebp-40h]
0040209C mov ecx, 10 h
004020A1 mov eax, 0 CCCCCCCCh
004020A6 rep stos dword ptr [edi]
252: return 0;
004020A8 xor eax, eax
253 :}
004020AA pop edi
004020AB pop esi
004020AC pop ebx
004020AD mov esp, ebp
004020AF pop ebp
004020B0 ret
250: static int process ()
251 :{
00402090 push ebp
00402091 mov ebp, esp
00402093 sub esp, 40 h
00402096 push ebx
00402097 push esi
00402098 push edi
00402099 lea edi, [ebp-40h]
0040209C mov ecx, 10 h
004020A1 mov eax, 0 CCCCCCCCh
004020A6 rep stos dword ptr [edi]
252: return 0;
004020A8 xor eax, eax
253 :}
004020AA pop edi
004020AB pop esi
004020AC pop ebx
004020AD mov esp, ebp
004020AF pop ebp
004020B0 ret
As you can see, this is the real recursive exit. After this, the function starts to return, which means our computing is about to end. All procedures are very similar to recursion. The difference between recursive functions and template recursion is That recursive functions are completed during code execution and template recursion is completed during compilation.
Questions:
Compile a factorial function by yourself? Can I convert it into a recursive function? Can I use a template class for recursion?