Valid C ++ Clause 44 and valid Clause 44
The title of the terms in this section is: extract code irrelevant to parameters from templates
To learn about the terms of this section, you must first understand whether the template instantiation process will be repeated?
Here is an example:
#include<iostream>using namespace std;template <typename T>T Try(T m){ return m;}int main(){ Try(10); Try(1);}
Looking at the simple code above, everyone knows that the template has been called twice. Yes, this is obvious. But is the template also instantiated twice? In fact, the template is instantiated only once.
Let's take another example:
# Include <iostream> using namespace std; template <typename T> T Try (T m) {return m;} int main () {Try (10); Try (1.01 ); // note! This is a double type}
At this time, everyone knows that the template has been called twice. Is the template also instantiated twice? In fact, the template is indeed instantiated twice.
What do you understand by comparing the above two examples? That is, the number of template function instantiation and the number of calls are not directly related, but are related to the type of call. If the same type has been called, the template function will reuse the previous instantiation example without re-allocating the memory instantiation. If you understand this, you can understand the terms of this section.
We use the template to make the code shorter and the memory smaller. However, in general, many programmers can only do the first step, rather than making full use of code reuse in the memory.
An example is as follows:
Template <typename T, std: size_t n> // T indicates the data type, and n indicates the matrix size class SquareMatrix {public :...... Void invert (); // Inverse Calculation}; SquareMatrix <double, 5> sm1; sm1.invert (); // call SquareMatrix <double, 5 >:: invert SquareMatrix <double, 10> sm2; sm2.invert (); // call SquareMatrix <double, 10 >:: invert
The above code will embody two invert () functions during execution. These two functions are almost identical, So memory is a waste. To make up for this shortcoming, we can use the following comparison example:
template<typename T>class SquareMatrixBase{public: SquareMatrixBase(T* p) : DataPointer(p){} void Invert(size_t n){}private: T* DataPointer;};template <typename T, size_t n>class SquareMatrix: private SquareMatrixBase<T>{public: SquareMatrix() : SquareMatrixBase(Data) {} void Invert() { SquareMatrixBase::Invert(n); }private: T Data[n * n];}; SquareMatrix<double,5> sm1; sm1.invert(); SquareMatrix<double,10> sm2; sm2.invert();
When we call the preceding statement again, the SquareMatrixBase class instance is generated only once in the memory. Because each call is a double SquareMatrixBase. Then, the matrix data is accessed by pointers. The same data will not be copied multiple copies, which reduces memory usage.
In short, the following three are important:
1. The Template generates multiple classes and multiple functions. Therefore, no template code should be dependent on an expanded template parameter.
2. Code expansion caused by non-type template parameters can often be eliminated. The method is to replace the template parameter with function parameters or class member variables.
3. Code expansion caused by types can also be reduced by sharing the implementation code of the current type with identical binary expressions.