[C++] template (below)


1. The use of typename

We can use class when using template parameters, or use typename to define template parameters. Now typename has a new role

template<class container>
void Print(const container& v)
{
    
    
	//编译器不确定Container::const_iterator是类型还是对象
	//没有实例化的类模板,需要使用typename明确告诉编译器container是一个类型,否则编译器报错
	typename container::const_iterator it = v.begin();
	//也可使用auto  auto it=v.begin();
	while (it != v.end())
	{
    
    
		cout << *it << " ";
		it++;
	}
	cout << endl;
}

2. Non-type template parameters

Template parameters classify type parameters to non-type parameters.

Type parameter: Appears in the template parameter list, followed by the parameter type name such as class or typename.

Non-type parameter: It is to use a constant as a parameter of a class (function) template, and the parameter can be used as a constant in the class (function) template.

Example:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<list>
#include<array>
using namespace std;

//静态栈
//非类型模板参数
//1.常量
//2.必须是整形,不可在类中修改
template<class T,size_t N=10>   
class Stack
{
    
    
public:
	void func()
	{
    
    
		//常量,不可修改
		//N = 10;
	}
private:
	T _a[N];
	int _top;
};

int main()
{
    
    
	Stack<int, 10> st1;
	Stack<int, 100> st2;

	//st1.func();

	//非类型模板参数使用   定长数组  C++11
	//array只有一个优势,越界检查严格
	array<int,10> a;
	for (auto e : a)
	{
    
    
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

Implemented a new container using a non-type template parameter, array - fixed-length array

3. Template specialization

1. Concept

Usually, templates can be used to implement some type-independent codes, but for some special types, some wrong results may be obtained, which require special handling, for example: implement a function template specially used for less than comparison

namespace tzc
{
    
    
	template<class T>
	bool less(T a, T b)
	{
    
    
		return a < b;
	}
}
 
int main()
{
    
    
	int a = 10;
	int b = 20;
	int* c = &a;
	int* d = &b;
	cout << tzc::less(a, b) << endl;
	cout << tzc::less(c, d) << endl; // 传入指针 ,只会比较指针
	return 0;
}

insert image description here

We have implemented a function template to compare the size of two variables, but the type of comparison is limited. If a variable of pointer type is passed in, the result of comparing the size is often not what we want. At this time, we need to implement a function template. specialization to handle special cases

2. Template specialization of functions

The specialization steps of a function template:
1. There must be a basic function template first.
2. The keyword template is followed by a pair of empty angle brackets <>
3. The function name is followed by a pair of angle brackets, which specify that specialization is required Type
4. Function parameter table: must be exactly the same as the basic parameter type of the template function, if it is different, the compiler may report some strange errors.

//函数模板
template<class T>
bool Less(T left, T right)
{
    
    
	return left < right;
}

//函数模板的特化    也可重载
//这种只能解决int类型的问题
template<>
bool Less<int*>(int* left, int* right)
{
    
    
	return *left < *right;
}
//解决各种指针类型的比较,
template<class T>
bool Less(T* left, T* right)
{
    
    
	return *left < *right;
}

int main()
{
    
    
	cout << Less(1, 2) << endl;

	int a = 1, b = 2;
	cout << Less(&a, &b) << endl;
	return 0;
}

3. Template specialization of classes

① Full specialization

//类模板
template<class T1,class T2>
class Date
{
    
    
public:
	Date() {
    
     cout << "Date<T1 ,T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

//全特化
template<>
class Date<int ,double>
{
    
    
public:
	Date() {
    
     cout << "Date<int,double>" << endl; }
};

int main()
{
    
    
	Date<int, int> d1;
	Date<int, double>d2;
	return 0;
}

insert image description here

② partial specialization

//类模板
template<class T1,class T2>
class Date
{
    
    
public:
	Date() {
    
     cout << "Date<T1 ,T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

//偏特化,特化部分参数
template<class T>
class Date<T,double>
{
    
    
public:
	Date() {
    
     cout << "Date<T,double>" << endl; }
};

//偏特化,对某些类型进行进一步特化
template<class T1,class T2>
class Date<T1*,T2*>
{
    
    
public:
	Date() {
    
     cout << "Date<T*,T*>" << endl; }
};

int main()
{
    
    
	Date<double, double>d3;
	Date<int*, int*>d4;
	Date<double*, double*>d5;
	return 0;
}

insert image description here

Guess you like

Origin blog.csdn.net/Tianzhenchuan/article/details/131856029