C + + template primary

Posted by Ph0enix on Sun, 20 Feb 2022 04:30:30 +0100

Initial stage of formwork

The initial stage of the template is understood from three aspects:

1. Generic programming

2. Function template

3. Class template

Generic Programming

If you use function overloading to operate on different data types, there are the following problems:

1. The code reuse rate is low. If a new type appears, you need to implement a function with the same function for the new type.

2. The maintainability of the code is low. An error may lead to the overload error of all functions.

Therefore, generic programming came into being.

Definition: writing generic code independent of type is a means of code reuse. Templates are the foundation of generic programming.

In C + +, templates are used to realize generic programming.

Template

Templates are divided into function templates and class templates.

Function template

1. Concept: the function template represents a function family. The function template is independent of type and is parameterized when used. The specific type version of the function is generated according to the argument type.

2. Format:

​ template<typename T1, typename T2,......, Typename TN > return value type function name (parameter list) {}

Note: typename is a keyword that defines template parameters, and can also be replaced with class (not struct)

template <typename T>
void swap(T& a1,T& a2)
{
    T tmp=a1;
    a1=a2;
    a2=tmp;
}

3. Principle:

Function template is a blueprint. It is not a function itself. It is a mold that the compiler uses to generate specific types of functions. So in fact, the template is to give the compiler the repeated things we should have done.

In the compiler compilation stage, for the use of template functions, the compiler needs to deduce and generate functions of corresponding types according to the input argument types for calling. For example, when using the function template with double type, the compiler determines T as double type through the deduction of the argument type, and then generates a code specially dealing with double type, which is the same for character type.

4. Instantiation

When a function template is used with different types of parameters, it is called instantiation of the function template. Template parameter instantiation can be divided into implicit instantiation and explicit instantiation

4.1 implicit instantiation

Definition: let the compiler deduce the actual type of template parameters according to the actual parameters

4.2 explicit instantiation

· definition: specify the actual type of template parameter in < > after the function name

template <typename T>
void swap(T& a1,T& a2)
{
    T tmp=a1;
    a1=a2;
    a2=tmp;
}
​
int main()
{
    int a1=0,a2=10,a3=5;
    double d1=1.1,d2=2.2,d3=3.3;
    //implicit instantiation 
    swap(a1,a2);
    swap(d1,d2);
    //swap(a1,d1);  // Compilation fails. When the compiler sees the instantiation, it needs to deduce the actual parameter type. The template parameter has only one T, but this parameter passes two types of parameters. The compiler does not know which type to convert t to, resulting in an error.
    //In the template, the compiler generally does not carry out type conversion, because once there is a problem with conversion, the compiler needs to bear the blame
    
    //In this area, you can do your own type conversion to solve the problem
    swap(a1,(int)d1);
    
    
    //Explicit Instantiation 
    //The compiler will try implicit type conversion and report an error if it cannot be converted.
    swap<int>(a1,d2);   //In this way, the compiler will convert all parameters to int type;
    
    
    
    return 0;
}

5. Template parameter matching principle

  1. : a non template function can exist simultaneously with a function template with the same name, and the function template can also be instantiated as this 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 called first during transfer, and an instance will not be generated from the template. If the template can produce a function with a better match, the template will be selected

  3. : template functions do not allow automatic type conversion, but ordinary functions can perform automatic type conversion

Class template

Template class format

template<class T1, class T2, ..., class Tn>
class Class template name
{
// Intra class member definition
};

Vector implementation:

// Dynamic sequence table
// Note: Vector is not a concrete class, but a mold for the compiler to generate a concrete class according to the instantiated type
template<class T>
class Vector
{
public :
    Vector(size_t capacity = 10)
        : _pData(new T[capacity])
        , _size(0)
        , _capacity(capacity)
    {}
// Demonstration using destructors: declared in a class and defined outside the class.
    ~Vector();
    void PushBack(const T& data);
    void PopBack();
    // ...
    size_t Size() {return _size;}
    T& operator[](size_t pos)
    {
        assert(pos < _size);
        return _pData[pos];
    }
private:
    T* _pData;
    size_t _size;
    size_t _capacity;
};
// Note: when the functions in the class template are defined outside the class, the template parameter list needs to be added
template <class T>
Vector<T>::~Vector()
{
    if(_pData)
    delete[] _pData;
    _size = _capacity = 0;
}

Class template instantiation:

Class template instantiation is different from function template instantiation. Class template instantiation needs to be followed by < >, and then put the instantiated type in < >. The class template name is not a real class, but the instantiation result is a real class.

//Vector class name, vector < int > is the type
Vector<int> s1;
Vector<double> s2;

Topics: C++ Back-end