C + + learning diary 5 - template

catalogue

I. concept of templates

1.1 concept

1.2 features

2, Function template

2.1 function template

2.2 precautions for function template

2.3} function template cases

2.4 differences between ordinary functions and function templates

2.5 call rules for ordinary functions and function templates

2.6 limitations of formwork

3, Class template

3.1 class template syntax

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

4, Comprehensive case

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

...

Keywords: C++

Added by thebutler on Tue, 08 Mar 2022 03:27:51 +0200