Basic knowledge

In Java, they’re called generics. In c++, they’re called templates. In keeping with Java, it’s called generics, which is familiar

  1. Divided into generic functions and generic classes, the same as Java.

Generic function

Add template

to the method declaration/definition, where T represents the generic class

Do not overload generic functions with normal functions to avoid ambiguity

  1. When defining generics, the compiler can derive them automatically or specify them directly. This is the same with Java

  2. Generics must be deducible or specified. For example, if a generic type is defined but not used, then the call must also specify the generic type, otherwise the specific type of the generic type cannot be derived and an error will be reported

    Example:

    // Declare generics
    template<typename T>
    void test(T& t1,T& t2){
        T t = t1;
        t1 = t2;
        t2 = t;
    }
    / / call
    int a = 10.0;
    int b = 20.0;
    test(a, b);// automatically derive the generic type as int
    test<int>(a,b);// // can also be specified directly
    Copy the code
  3. Common function and generic function call rules, call the same method may hit the ordinary function, also hit the generic function. Call as follows:

    • Call normal functions first
    • You can force generic methods to be called by specifying empty generic parameters. Empty template parameters are written as follows:Add <> after method, and no arguments are added to Angle brackets
    • If a generic function achieves a better match, it is called. A better match is a better match between the types of method parameters
  4. It is best that normal and generic functions are not overloaded

  5. Generic functions can be externalized. It is possible to use methods in a generic function that are not available for the passed argument, such as comparing a custom class. This is where ** is needed

    
    template<class T>
    void test(T t1,T t2){
        cout << "Generic" << endl;
    }
    // If two of test's arguments are ints, this method will be called instead of the above generic function
    template<> void test(int a, int b){
        cout << (a+b) << endl;
    }
    Copy the code

A generic class

  1. The syntax is the same as for generic functions, with template

    on top of the class.

  2. Generic classes do not have automatic type inference, which means that when you use a generic class you must explicitly specify all the actual types of the generic

  3. Generics in generic classes can have default classes, which also alleviates some of the shortcomings in 2

    // Define two generics
    // The second one defaults to int. The second one can be passed either when using the Test class (in which case the second generic is int) or when using the Test class
    template<class First.class Second = int>
    class Test{};
    Copy the code
  4. The member functions of a generic class created in the call, this means that the generic class members can use the generic call any method, the compilation phase won’t be an error (because these methods may exist, or may not exist, have to wait until runtime to determine), the actual type of the generic type at runtime has identified, you can judge the method called exists

  5. When a subclass inherits a generic class, it must specify a generic argument for the parent class. Either a specific type is specified directly, or a subclass is also declared as a generic class, as in Java

  6. Member methods can be declared inside a class and implemented outside it. The out-of-class implementation of a generic class also needs to specify generics, which can be used when defining generic header files, CPP files

    // declared in the header file
    template<class A>
    class Test{
    public:
        void test(a);
        void test(A& a);
    };
    // CPP file implementation
    template<class A>
    void Test<A>::test(){
        cout << "no" << endl;
    }
    Copy the code
  7. As we know, classes can be written in files: a header file and a CPP file. For generic classes, however, file-splitting is an error, mainly because member methods are not generated at compile time, and if only the header file is included, some of the methods called will not be found. There are two solutions to this, which boils down to an include implementation file:

    • Include CPP files directly
    • To write the header and CPP files into one file, the general practice is to suffix the file HPP and then include the HPP file directly
  8. Template

    class Test;