[C++] plantilla (abajo)


1. El uso del nombre de tipo

Podemos usar clase cuando usamos parámetros de plantilla, o usar typename para definir parámetros de plantilla. Ahora typename tiene un nuevo rol

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. Parámetros de plantilla sin tipo

Los parámetros de plantilla clasifican los parámetros de tipo en parámetros que no son de tipo.

Parámetro de tipo: aparece en la lista de parámetros de la plantilla, seguido del nombre del tipo de parámetro, como clase o nombre de tipo.

Parámetro de no tipo: es para usar una constante como parámetro de una plantilla de clase (función), y el parámetro se puede usar como una constante en la plantilla de clase (función).

Ejemplo:

#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;
}

Implementó un nuevo contenedor utilizando un parámetro de plantilla que no es de tipo, matriz - matriz de longitud fija

3. Especialización de plantillas

1. Concepto

Por lo general, las plantillas se pueden usar para implementar algunos códigos independientes del tipo, pero para algunos tipos especiales, se pueden obtener algunos resultados incorrectos que requieren un manejo especial, por ejemplo: implementar una plantilla de función especialmente utilizada para menos que comparación

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;
}

inserte la descripción de la imagen aquí

Hemos implementado una plantilla de función para comparar el tamaño de dos variables, pero el tipo de comparación es limitado. Si se pasa una variable de tipo puntero, el resultado de comparar el tamaño a menudo no es el que queremos. En este momento, necesita implementar una plantilla de función especialización para manejar casos especiales

2. Plantilla de especialización de funciones

Los pasos de especialización de una plantilla de función:
1. Primero debe haber una plantilla de función básica
2. La plantilla de palabra clave va seguida de un par de corchetes angulares vacíos <>
3. El nombre de la función va seguido de un par de corchetes angulares, que especificar la necesidad de especialización 4.
Tabla de parámetros de función: debe ser exactamente igual que el tipo de parámetro básico de la función de plantilla, si es diferente, el compilador puede informar algunos errores extraños.

//函数模板
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. Plantilla de especialización de clases

① Especialización completa

//类模板
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;
}

inserte la descripción de la imagen aquí

② especialización parcial

//类模板
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;
}

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Tianzhenchuan/article/details/131856029
Recomendado
Clasificación