English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
C++os modelos podem ser divididos em duas grandes categorias: funções de modelo, classes de modelo. Este artigo escreve sobre funções de modelo, e será introduzido o modelo de classe a seguir.
definição: a função de modelo é uma descrição de função genérica, ou seja, elas usam tipos genéricos para definir, onde os tipos genéricos podem ser substituídos por tipos específicos.
exemplo de código:
#include <iostream> //declaração da classe de modelo template<typename T> void Swap(T& a,T& b); int main() { int i = 10; int j = 20; std::cout<<"i=" << i << "," << "j=" <<j; Swap(i,j);//gerar void Swap(int &,int&); std::cout<<"i=" << i << "," << "j=" <<j; double x = 11.5; double y = 19.5; std::cout<<"x=" << x << "," << "y=" <<y; Swap(x,y);//O compilador gera void Swap(double &,double&); std::cout<<"x=" << x << "," << "y=" <<y; return 0; } //Definição da classe de modelo template<typename T> void Swap(T& a,T& b) { T temp; temp = a; a = b; b = temp; }
O exemplo acima é a instância mais simples de modelo de função, o compilador gerará a função correspondente com base no tipo específico usado.
sobre carga do modelo:
Quando é necessário usar o mesmo algoritmo para diferentes tipos, pode-se usar modelos, como mostrado no código acima. No entanto, não todos os tipos usam o mesmo algoritmo. Para atender a essa necessidade, pode-se sobrecarregar a definição do modelo de maneira semelhante à sobrecarga da definição de função convencional. Como na sobrecarga da função convencional, a tabela de características da função deve ser diferente. Um exemplo de código é fornecido a seguir:
#include <iostream> //declaração da classe de modelo template<typename T> void Swap(T& a,T& b); const int iCount = 5; template<typename T> void Swap(T* a,T*b, int n); int main() { int i = 10; int j = 20; std::cout<<"i=" << i << "," << "j=" <<j; Swap(i,j);//gerar void Swap(int &,int&) std::cout<<"i=" << i << "," << "j=" <<j; double x = 11.5; double y = 19.5; std::cout<<"x=" << x << "," << "y=" <<y; Swap(x,y);//O compilador gera void Swap(double &,double&); std::cout<<"x=" << x << "," << "y=" <<y; int d[iCount] = {0,1,2,3,4}; int e[iCount] = {5,6,7,8,9}; Swap(d,e,iCount);//Correspondência do novo modelo, realizando a troca de arrays return 0; } //Definição da classe de modelo template<typename T> void Swap(T& a,T& b) { T temp; temp = a; a = b; b = temp; } template<typename T> void Swap(T* a,T*b,int n) { for (int i=0;i<iCount;++i) { T temp; temp = a[i]; a[i] = b[i]; b[i] = temp; } }
Como o código acima adicionou um modelo para trocar os elementos de dois arrays, o sinalizador característico do modelo original é (T&,T&), e o sinalizador característico do novo modelo é (T[],T[]),int). Note que no último modelo, o tipo do último parâmetro é um tipo específico (int), não um tipo genérico, e não todos os parâmetros do modelo precisam ser tipos de parâmetro de modelo.
Especificação explícita:
Para o nome da função dado, podem existir funções não-modelo, funções de modelo e funções de específicação explícita do modelo, bem como suas versões sobrecarregadas.
A específicação explícita e a definição do protótipo devem começar com template<> e usar o nome para indicar o tipo.
A específicação explícita cobrirá o modelo comum, e a função não-modelo cobrirá a específicação explícita e o modelo comum.
A seguir está a função não-modelo usada para trocar a estrutura Job, o protótipo da função de modelo e a específicação explícita.
void Swap(job &,job&);//Função não-modelo template <typename T> void Swap(T&,T&);//Função de modelo template <> void Swap<job>(job&,job&);//Função de específicação explícita, onde o parâmetro job após Swap pode ser removido, a assinatura da função é template <> void Swap(job&,job&);
Foi mencionado anteriormente que, se houver vários protótipos, o compilador dará prioridade ao não-modelo sobre a específicação explícita e a versão do modelo, e a específicação explícita dará prioridade à versão gerada pelo modelo.
como nas chamadas a seguir:
double u, v;
Swap(u, v);//Use o modelo genérico
job a, b;
swap (a, b)//Use a versão de especificação explícita.
Instânciação e especificação:
Para entender melhor os modelos, é necessário compreender os termos instânciação e especificação. Lembre-se de que incluir o próprio modelo de função no código não gera uma definição de função, é apenas um plano para gerar definições de função. Quando o compilador gera uma definição específica para um tipo usando o modelo, ele obtém uma instância do modelo (instantiação). Por exemplo: a chamada de função Swap(i, j) faz o compilador gerar uma instância de Swap(), que usa o tipo int. O modelo não é uma definição de função, mas a instância do modelo usando int é uma definição de função. Esse tipo de instânciação é chamado de instânciação implícita, porque o compilador sabe que precisa definir devido aos parâmetros int fornecidos na chamada Swap().
Agora, o compilador ainda pode permitir a instânciação de exibição, o que significa que você pode comandar diretamente o compilador para gerar instâncias específicas, como Swap<int>. Sua sintaxe é declarar o tipo escolhido-Use os símbolos <> para indicar o tipo e adicione a palavra-chave template no início da declaração:
template void Swap<int>(int, int);//Instânciação de exibição
Os compiladores que implementam essa característica, ao verem as declarações acima, usarão o modelo Swap() para gerar uma instância do tipo int.
Diferente da instânciação de exibição, a especificação de exibição usa uma das duas declarações equivalentes a seguir:
template <> void Swap<int>(int, int); template <> void Swap(int, int);
A diferença está na seguinte: o significado dessas declarações é 'não use o modelo Swap() para gerar definições de função, mas use definições de função independentes e específicas para gerar definições de função do tipo int'.
Atenção: Tentar usar o mesmo tipo de especificação de exibição e instânciação em um único módulo de programação resultará em erro.
O que foi mencionado acima é o que o editor++Detalhamento das funções de modelo, esperamos que sejam úteis para vocês. Se tiverem alguma dúvida, por favor, deixem um comentário.