Primeiro conhecimento de modelos

Os modelos são a base para a realização da programação genérica . Programação genérica refere-se à escrita de códigos lógicos que nada têm a ver com tipos, e é um meio para conseguir reutilização.

Os modelos podem ser divididos em: modelos de função, modelos de classe

Template de função

conceito

O template de função representa uma família de funções. O template de função não tem nenhuma relação com o tipo. Ele é parametrizado quando usado, e uma versão de tipo específico da função é gerada de acordo com o tipo do parâmetro atual.

Formato de modelo de função

template<typename T1,typename T2,……,typename Tn>
返回值类型 函数名(形参列表){
    
    函数体}

Tal como:

template<typename T>
void Swap(T& left,T& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}//一个可以实现交换功能的函数模板

[Nota]: typename Também pode ser usado no classlugar

O princípio do template de função

Um template de função é um molde para o compilador gerar um tipo específico de função, não uma função em si !

Durante a fase de compilação do compilador, quando um modelo de função precisa ser usado para gerar uma função de um tipo específico, o compilador determinará o tipo de entrada T por meio da dedução dos tipos de parâmetros reais e, em seguida, gerará uma função especializada em processar o tipo T.

Tal como:

double a = 3.14, b = 6.28;
int  x = 1,y = 2;
char r = 'a', t = 'v';
Swap(a,b);
Swap(x,y);
Swap(r,t);

Por causa Swapdo modelo de função no código, diferentes tipos de dados são passados ​​nas três chamadas e o compilador infere o tipo de cada dado de entrada no estágio e gera as respectivas funções correspondentes .

O código acima terá mais 3 funções na fase de compilação:

void Swap(double& left,double& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}
void Swap(int& left,int& right){
    
    
	int tmp = left;
	left = right;
	right = tmp; 
}
void Swap(char& left,char& right){
    
    
	char tmp = left;
	left = right;
	right = tmp; 
}

Essas três funções correspondem a três chamadas da função Swap respectivamente . Nós apenas escrevemos um modelo de função, mas no código final, diferentes tipos de parâmetros reais serão passados, resultando em muito mais funções. Em outras palavras, o código que usa o modelo tem o problema de inchaço do código.

No entanto, acho que não precisamos de modelos de função para alcançar as mesmas funções para diferentes tipos de dados. Parece que só podemos implementar funções por meio de sobrecarga de função e ainda temos que escrever muitas funções. O uso de modelos libera os desenvolvedores de escrever repetidamente funções da mesma função e de tipos diferentes, o que reduz em certa medida o conteúdo de trabalho ineficiente, mas inevitável, que é de pouca importância para os desenvolvedores, e melhora a eficiência do trabalho. Mesmo que haja um problema com a expansão do código que usa o modelo, parece que ele só se expandirá até o ponto em que o modelo não for usado. Este não é um problema inaceitável.

Instanciação de modelos de função

O processo pelo qual o compilador infere os tipos de argumentos de entrada e gera funções correspondentes para diferentes tipos é chamado de instanciação de modelos de função. A instanciação de modelo pode ser dividida em: instanciação implícita e instanciação explícita

Instanciação implícita

A instanciação implícita significa que o desenvolvedor não informa ao compilador o tipo de argumento transmitido e permite que o compilador deduza que tipo de função ele deve gerar com base no tipo de argumento transmitido . A seguir, não informamos ao compilador que tipo de argumento é passado.

template<typename T>
void Swap(T& left,T& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}//一个可以实现交换功能的函数模板

int main(){
    
    
	double a = 3.14, b = 6.28;
	Swap(a,b);//隐式实例化
	return 0;
}

Instanciação explícita

Para exibir a instanciação, só precisamos <>preencher o tipo de parâmetro real no nome da função,
como:

	Swap<double>(a,b);//显式实例化

Pessoalmente, acho que devemos usar instanciação explícita ao usar modelos de função, para que possamos compreender nosso próprio código e torná-lo mais fácil para os outros lerem.

Princípio de correspondência dos parâmetros do modelo

De modo geral, quando existem funções não-template e funções template que podem completar uma função, existe uma estratégia para ajudar o compilador a decidir como definir a função.

No vernáculo, existem muitos tipos de funções que podem completar a função especificada. Alguns compiladores de função nesta pilha de funções não precisam fazer nada. Corresponde exatamente à lista de parâmetros da função chamada; alguns requerem conversão de tipo implícita; Alguns têm conversões de tipo especificadas pelo desenvolvedor. Neste momento, se você deseja completar uma função, você tem muitas opções. Para evitar erros no resultado e evitar que o compilador salte para a esquerda e para a direita, existe uma estratégia de seleção para ajudar o compilador a escolher a função a ser chamada .

A estratégia de seleção de ajuste é a seguinte (a prioridade é organizada de cima para baixo):
1. Correspondência completa: o modelo de função e a função não modelo existem ao mesmo tempo e podem completar a função especificada, e os tipos não entram em conflito (o o uso de função não-modelo é preferível )
2. Conversão de atualização charCom conversão shortautomática int, conversão flaotautomática para double)
3. Conversão padrão ( intpara char, longpara transferir double)
4. Conversão definida pelo usuário, como a conversão definida na declaração de classe

Limitações de modelos

Suponha que existam as seguintes funções de modelo:

template<typename T>
void f(T a,T b){
    
    
	//函数体
}

De modo geral, haverá algumas operações na função.
Tal como:

a = b

Se for Tum tipo de dados integrado, essa atribuição estará de acordo com nossas expectativas.
Mas Tpara ser um tipo de estrutura array / string / não construído e assim por diante, o resultado provavelmente não atenderá às nossas expectativas.

Outro exemplo:

if(a>b)

Se Tfor uma matriz, a>ba comparação da matriz acom bo nível de endereço, provavelmente não é o que queremos.

Resumindo, as funções de modelo podem não ser capazes de lidar com certos tipos.
Precisamos lembrar que tudo tem dois lados! Não há nada absolutamente bom e nada absolutamente ruim.

Modelo de classe

Formato de modelo de classe

template<class T1,class T2,……,class Tn>
class 类模板名
{
    
    
	//类内成员定义
}

[Nota] Quando os membros da classe no modelo de classe são definidos fora da classe, a lista de parâmetros do modelo precisa ser adicionada

Instanciação do modelo de classe

Diferente da instanciação do modelo de função, a instanciação do modelo de classe precisa ser adicionada após o nome do modelo de classe <>e, em seguida, o tipo instanciado é colocado <>. Ou seja, ele deve ser explicitamente instanciado.

A mesma explicação se aplica aos modelos de classe : modelos de classe não são classes! O resultado da instanciação do modelo de classe é a classe!

Acho que você gosta

Origin blog.csdn.net/qq_39208237/article/details/115342214
Recomendado
Clasificación