catalogue
2.2 precautions for function template
2.4 differences between ordinary functions and function templates
2.5 call rules for ordinary functions and function templates
3.2 difference between class template and function template
3.3. Creation time of member function in class template
3.4 function parameters for class template objects
Class 3.5 template and inheritance
3.6 implementation outside class of class template member function
3.7 preparation of class I template by document
Class 3.8 templates and friends
C + + improvement phase:
This stage mainly focuses on C + + generic programming and STL technology, and discusses the deeper use of C + +
I. concept of templates
1.1 concept
Template is to establish a general mold, which greatly improves the reusability
For example:
(1) One inch photo template
(2) PPT template
1.2 features
The template can't be used directly. It's just a framework
The universality of templates is not everything
2, Function template
Another programming idea of C + + is called generic programming, which mainly uses template technology
C + + provides two template mechanisms: function template and class template
2.1 function template
1. Function template function:
Establish a general function whose function return value type and formal parameter type can be represented by a virtual type without specific formulation.
2. Syntax:
template<typename T> Function declaration or definition
3. Explanation:
Template -- declare the creation of a template
typename -- the symbol behind the surface is a data type, which can be replaced by class
T -- General data type, the name can be replaced, usually in uppercase letters
4. Example:
Original wording:
void swapInt(int& a, int& b) { double temp = a; a = b; b = temp; } void swapDouble(double& a, double& b) { double temp = a; a = b; b = temp; }
Revised wording:
#include<iostream> using namespace std; #include<string> template<typename T> void mySwap(T& a, T& b) { T temp = a; a = b; b = temp; } void test() { int a = 10; int b = 20; // 1. Automatic type derivation mySwap(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl << endl; // 2. Displays the specified type mySwap<int>(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl; } int main() { test(); system("pause"); return 0; }
2.2 precautions for function template
For automatic type derivation, a consistent data type T must be derived before it can be used
The template can be used only after the data type of T is determined
#include<iostream> using namespace std; #include<string> template<class T> // typename can be replaced by class void mySwap(T& a, T& b) { T temp = a; a = b; b = temp; } void test() { int a = 10; int b = 'b'; // Error: inconsistent T type deduced mySwap(a, b); } template<class T> void func() { cout << "func call" << endl; } void test2() { // Note: you must add < int > func<int>(); } int main() { test(); test2(); system("pause"); return 0; }
2.3} function template cases
Case description:
Using the function template to encapsulate a sorting function, you can sort arrays of different data types
The sorting rules are from large to small, and the sorting algorithm is selective sorting
Test with char array and int array respectively
#include <iostream> using namespace std; //Exchanged function templates template<typename T> void mySwap(T& a, T& b) { T temp = a; a = b; b = temp; } template<class T> // You can also replace it with typename //Select sorting is used to sort the array from large to small void mySort(T arr[], int len) { for (int i = 0; i < len; i++) { int max = i; //Subscript of maximum number for (int j = i + 1; j < len; j++) { if (arr[max] < arr[j]) { max = j; } } if (max != i) //If the subscript of the maximum number is not i, swap the two { mySwap(arr[max], arr[i]); } } } template<typename T> void printArray(T arr[], int len) { for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout << endl; } void test() { // Test char array char charArr[] = "badcfe"; int intArr[] = { 7,5,4,1,9,2,3,6,8 }; int num = sizeof(charArr) / sizeof(char); mySort(charArr, num); printArray(charArr, num); } int main() { test(); system("pause"); return 0; }
2.4 differences between ordinary functions and function templates
1. Differences between ordinary functions and function templates:
(1) Automatic type conversion (implicit type conversion) can occur when calling ordinary functions
(2) When a function template is called, if automatic type derivation is used, implicit type conversion will not occur
(3) Implicit type conversion can occur if the specified type is displayed
#include <iostream> using namespace std; int myAdd01(int a, int b) { return a + b; } template<class T> T myAdd02(T a, T b) { return a + b; } void test() { int a = 10; int b = 20; char c = 'c'; cout << myAdd01(a, c) << endl; cout << myAdd02<int>(a, c) << endl; } int main() { test(); system("pause"); return 0; }
2.5 call rules for ordinary functions and function templates
The calling rules are as follows:
(1) If both function templates and ordinary functions can be implemented, ordinary functions will be called first
(2) You can force a function template to be called through an empty template parameter list
(3) Function templates can also be overloaded
(4) If the function template can produce a better match, call the function template first
1. If both function templates and ordinary functions can be implemented, ordinary functions will be called first
#include <iostream> using namespace std; void myPrint(int a, int b) { cout << "Ordinary functions are called" << endl; } template<class T> void myPrint(T a, T b) { cout << "Called template" << endl; } void test() { int a = 10; int b = 20; myPrint(a, b); } int main() { test(); system("pause"); return 0; }
2. You can force a function template to be called through an empty template parameter list
void test() { int a = 10; int b = 20; myPrint<>(a, b); }
3. Function templates can also be overloaded
template<class T> void myPrint(T a, T b, T c) { cout << "Called template" << endl; } void test() { int a = 10; int b = 20; myPrint(a, b, 100); }
2.6 limitations of formwork
1. Limitations:
The versatility of templates is not everything
template<class T> void f(T a, T b) { a = b; }
The assignment operation provided in the above code cannot be implemented if the passed in a and b are an array
template<class T> void f(T a, T b) { if (a > b) { ... } }
In the above code, if the incoming data type is a user-defined data type such as Person, it will not work normally
2. Code
#include <iostream> using namespace std; #include <string> class Person { public: Person(string name, int age) { this->Name = name; this->Age = age; } string Name; int Age; }; template<class T> bool myCompare(T &a, T &b) { if (a == b) { return true; } else { return false; } } // 1. Operator overloading // 2. Materialize the version implementation code of Person (materialization is preferred) template<> bool myCompare(Person &p1, Person &p2) { if (p1.Name == p2.Name && p1.Age == p2.Age) { return true; } else { return false; } } void test01() { int a = 10; int b = 20; bool ret = myCompare(a, b); if (ret) { cout << "a == b" << endl; } else { cout << "a != b" << endl; } } void test02() { Person p1("Tom", 10); Person p2("Tom", 11); bool ret = myCompare(p1, p2); if (ret) { cout << "p1 == p2" << endl; } else { cout << "p1 != p2" << endl; } } int main() { test02(); system("pause"); return 0; }
3, Class template
3.1 class template syntax
1. Class template function:
Through a general class, the member data types in the class can be represented by a virtual type without specific formulation.
2. Code
#include <iostream> using namespace std; #include <string> template<class NameType, class AgeType> class Person { public: Person(NameType name, AgeType age) { this->Name = name; this->Age = age; } void showPerson() { cout << Name << " " << Age << endl; } NameType Name; AgeType Age; }; void test() { Person<string, int> p1("Sun WuKong", 999); p1.showPerson(); } int main() { test(); system("pause"); return 0; }
3.2 difference between class template and function template
1. There are two main differences between class templates and function templates:
(1) Class templates do not use automatic type derivation
(2) Class templates can have default parameters in the template parameter list
2. Code
// 1. Class template has no automatic type derivation usage // That is, Person p1("Monkey King", 999) cannot be used; Person<string, int> p1("Sun WuKong", 999); // 2. Class templates can have default parameters in the template parameter list template<class NameType, class AgeType = int> Person<string> p2("Zhu Bajie", 999);
3.3. Creation time of member function in class template
1. The creation timing of member functions in class templates is different from that in ordinary classes:
(1) Member functions in ordinary classes can be created from the beginning
(2) Member functions in class templates are created only when called
2. Code:
#include <iostream> using namespace std; #include <string> class Person1 { public: void showPerson1() { cout << "Person1 show" << endl; } }; class Person2 { public: void showPerson2() { cout << "Person2 show" << endl; } }; template<class T> class MyClass { public: T obj; // Member functions in class templates void func1() { obj.showPerson1(); } void func2() { obj.showPerson2(); } }; void test() { MyClass<Person1> m; m.func1(); // The following does not work // m.func2(); } int main() { test(); system("pause"); return 0; }
3. Summary:
The member function in the class template is not created at the beginning, but only when called
3.4 function parameters for class template objects
1. Learning objectives:
The object instantiated by the class template is the way to pass parameters to the function
2. There are three incoming methods:
(1) Specify the type passed in -- directly display the data type of the object
(2) Parameter templating -- change the parameters in the object into templates for transfer
(3) Whole class templating -- passing this object type Templating
3. Code
#include <iostream> using namespace std; #include <string> template<class NameType, class AgeType> class Person { public: Person(NameType name, AgeType age) { this->Name = name; this->Age = age; } void showPerson() { cout << Name << " " << Age << endl; } NameType Name; AgeType Age; }; // 1. Specify incoming type void printPerson1(Person<string, int> &p) { p.showPerson(); } void test1() { Person<string, int> p("Sun WuKong", 999); printPerson1(p); } // 2. Parameter Templating template<class NameType, class AgeType> void printPerson2(Person<NameType, AgeType> &p) { p.showPerson(); cout << "NameType The types of are:" << typeid(NameType).name() << endl; cout << "AgeType The types of are:" << typeid(AgeType).name() << endl; } void test2() { Person<string, int> p("Zhu Bajie", 999); printPerson2(p); } // 3. Whole class Templating template<class T> void printPerson3(T& p) { p.showPerson(); cout << "T The types of are:" << typeid(T).name() << endl; } void test3() { Person<string, int> p("Tang Monk", 999); printPerson3(p); } int main() { test1(); test2(); test3(); system("pause"); return 0; }
4. Summary:
There are three ways to pass parameters to functions for objects created through class templates
The first one is widely used: specify the type of incoming
Class 3.5 template and inheritance
1. When the class template encounters inheritance, you should pay attention to the following points:
(1) When the parent class inherited by the subclass is a class template, when declaring the subclass, specify the type of T in the parent class
(2) If not specified, the compiler cannot allocate memory to subclasses
(3) If you want to flexibly specify the type of T in the parent class, the subclass also needs to be changed into a class template
2. Code
#include <iostream> using namespace std; template<class T> class Base { public: T m; }; // Mode 1 class Son : public Base<int> { }; // In the template, you need to specify the parent and child types in the template template<class T1, class T2> class Son2 : public Base<T2> { T1 obj; }; void test() { Son s1; Son2<int, char> s2; } int main() { test(); system("pause"); return 0; }
3.6 implementation outside class of class template member function
1. Learning objectives:
Be able to master the out of class implementation of member functions in class templates
2. Code:
#include <iostream> using namespace std; #include <string> template<class NameType, class AgeType> class Person { public: Person(NameType name, AgeType age); void showPerson(); NameType Name; AgeType Age; }; // Constructor out of class implementation template<class NameType, class AgeType> Person<NameType, AgeType>::Person(NameType name, AgeType age) { this->Name = name; this->Age = age; } // Out of class implementation of member function template<class NameType, class AgeType> void Person<NameType, AgeType>::showPerson() { cout << Name << " " << Age << endl; } void test() { Person<string, int> p("Tang Monk", 999); p.showPerson(); } int main() { test(); system("pause"); return 0; }
3.7 preparation of class I template by document
Method 1:
Method 2:
Class 3.8 templates and friends
1. Learning objectives:
Master the in class and out of class implementation of class template and friend function
Implementation of global functions in class -- just declare friends in the class directly
Out of class implementation of global functions - the compiler needs to know the existence of global functions in advance
4, Comprehensive case
...