templates c with examples
Aprenda os vários aspectos dos modelos em C ++.
Os modelos são um dos recursos mais poderosos do C ++. Os modelos nos fornecem o código que é independente do tipo de dados.
Em outras palavras, usando modelos, podemos escrever um código genérico que funciona em qualquer tipo de dados. Precisamos apenas passar o tipo de dado como parâmetro. Este parâmetro que passa o tipo de dados também é chamado de nome de tipo.
Neste tutorial, exploraremos tudo sobre modelos e seus vários aspectos em detalhes.
=> Clique aqui para ver a série de treinamento Absolute C ++.
O que você aprenderá:
- O que são modelos?
- Como usar modelos / implementação?
- typename vs. palavra-chave de classe
- Instanciação e especialização de modelo
- Especialização de modelo
- Modelos C ++ Variadic
- Conclusão
- Leitura recomendada
O que são modelos?
Conforme mencionado acima, os modelos são genéricos, ou seja, independentes do tipo de dados. Os modelos são usados principalmente para garantir a capacidade de reutilização do código e a flexibilidade dos programas. Podemos apenas criar uma função simples ou uma classe que tenha o tipo de dados como parâmetro e implementar o código que funciona para qualquer tipo de dados.
Por exemplo, se quisermos que um algoritmo de classificação funcione para todos os tipos de dados numéricos, bem como cadeias de caracteres, então vamos apenas escrever uma função que recebe o tipo de dados como argumento e implementar a técnica de classificação.
Então, dependendo do tipo de dados (nome do tipo) que é passado para o algoritmo de classificação, podemos ter os dados classificados independentemente do tipo de dados. Dessa forma, não precisamos escrever dez algoritmos para dez tipos de dados.
Assim, os modelos podem ser usados em aplicativos em que exigimos que o código seja utilizável para mais de um tipo de dados. Os modelos também são usados em aplicativos em que a reutilização do código é de extrema importância.
Como usar modelos / implementação?
Os modelos podem ser implementados de duas maneiras:
- Como um modelo de função
- Como modelo de classe
Template de Função
O modelo de função é como uma função normal, mas a única diferença é que a função normal pode funcionar apenas em um tipo de dados e um código de modelo de função pode funcionar em vários tipos de dados.
Embora possamos realmente sobrecarregar uma função normal para trabalhar em vários tipos de dados, os modelos de função são sempre mais úteis, pois temos que escrever o único programa e ele pode funcionar em todos os tipos de dados.
A seguir, veremos a implementação de modelos de funções.
A sintaxe geral do modelo de função é:
template T function_name(T args){ …… //function body }
Aqui, T é o argumento do modelo que aceita diferentes tipos de dados e class é uma palavra-chave. Em vez da classe de palavra-chave, também podemos escrever ‘nome de tipo’.
Quando um determinado tipo de dados é passado para function_name, uma cópia desta função é feita pelo compilador com este tipo de dados como um argumento e função são executados.
Vejamos um exemplo para entender melhor os modelos de função.
#include using namespace std; template void func_swap(T &arg1, T &arg2) { T temp; temp = arg1; arg1 = arg2; arg2 = temp; } int main() { int num1 = 10, num2 = 20; double d1 = 100.53, d2 = 435.54; char ch1 = 'A', ch2 = 'Z'; cout << 'Original data
'; cout << 'num1 = ' << num1 << ' num2 = ' << num2<Modelos de classes Como nos modelos de função, podemos ter um requisito para ter uma classe que seja semelhante a todos os outros aspectos, mas apenas diferentes tipos de dados.
Nessa situação, podemos ter diferentes classes para diferentes tipos de dados ou diferentes implementações para diferentes tipos de dados na mesma classe. Mas fazer isso tornará nosso código volumoso.
A melhor solução para isso é usar uma classe de modelo. A classe de modelo também se comporta de maneira semelhante aos modelos de função. Precisamos passar o tipo de dados como um parâmetro para a classe ao criar objetos ou chamar funções de membro.
A sintaxe geral do modelo de classe é:
template class className{ ….. public: T memVar; T memFunction(T args); };
Na definição acima, T atua como um espaço reservado para o tipo de dados. MemVar e memFunction dos membros públicos também usam T como um espaço reservado para tipos de dados.
Depois que uma classe de modelo é definida como acima, podemos criar objetos de classe da seguinte maneira:
className classObejct1; className classObject2; className classObject3;
Vamos implementar um exemplo de código para demonstrar os modelos de classe:
#include using namespace std; template class myclass { T a, b; public: myclass (T first, T second) {a=first; b=second;} T getMaxval (); }; template T myclass::getMaxval () { return (a>b? a : b); } int main () { myclass myobject (100, 75); cout<<'Maximum of 100 and 75 = '< Resultado:
Máximo de 100 e 75 = 100
Máximo de ‘A’ e ‘a’ = a
O programa acima implementa um exemplo de modelo de classe. Temos a classe de modelo myclass. Dentro disso, temos um construtor que inicializará os dois membros aeb da classe. Há outra função de membro getMaxval que também é um modelo de função que retorna no máximo a e b.
Na função principal, construímos dois objetos, myobject do tipo integer e mychobject do tipo character. Em seguida, chamamos a função getMaxval em cada um desses objetos para determinar o valor máximo.
Observe que, além dos parâmetros de tipo de modelo (parâmetros do tipo T), as funções de modelo também podem ter parâmetros comuns como funções normais e também valores de parâmetro padrão.
typename vs. palavra-chave de classe
Ao declarar a classe ou função do template, usamos uma das duas palavras-chave class ou typename. Essas duas palavras são semanticamente equivalentes e podem ser usadas indistintamente.
Mas, em alguns casos, não podemos usar essas palavras como equivalentes. Por exemplo, quando estamos usando tipos de dados dependentes em modelos como “typedef”, usamos typename em vez de classe.
Além disso, a palavra-chave class deve ser usada quando temos que instanciar explicitamente um template.
Instanciação e especialização de modelo
Os modelos são escritos de forma genérica, o que significa que é uma implementação geral, independentemente do tipo de dados. De acordo com o tipo de dados fornecido, precisamos gerar uma classe concreta para cada tipo de dados.
Por exemplo, se tivermos um algoritmo de classificação de modelo, podemos gerar uma classe concreta para classificação, outra classe para classificação, etc. Isso é chamado de instanciação do modelo.
Substituímos os argumentos do modelo (tipos de dados reais) pelos parâmetros do modelo na definição da classe do modelo.
Por exemplo,
template class sort {};
Quando passamos o tipo de dados, o compilador substitui o tipo de dados por ‘T’ para que o algoritmo de classificação se torne classificação.
Cada vez que usamos uma classe ou função de modelo, há uma necessidade de uma instância quando passamos um tipo de dado particular. Se essa instância ainda não estiver presente, o compilador criará uma com o tipo de dados específico. Esta é a instanciação implícita.
Uma desvantagem da instanciação implícita é que o compilador gera classe de instância apenas para os argumentos que são usados atualmente. Isso significa que se quisermos gerar uma biblioteca de instâncias antes do uso dessas instâncias, precisamos ir para a instanciação explícita.
Um exemplo de declaração de modelo é fornecido abaixo:
template class Array(T)
Pode ser explicitamente instanciado como:
template class Array
Quando uma classe é instanciada, todos os seus membros também são instanciados.
Especialização de modelo
Ao programar usando modelos, podemos nos deparar com uma situação em que podemos exigir uma implementação especial para um determinado tipo de dados. Quando tal situação ocorre, optamos pela especialização de modelo.
Na especialização de modelo, implementamos um comportamento especial para um determinado tipo de dados, além da definição do modelo original para os outros tipos de dados.
Por exemplo, considere que temos uma classe de modelo ' myIncrement ’ que tem um construtor para inicializar um valor e uma função de modelo toIncrement que aumenta o valor em 1.
Esta classe particular funcionará perfeitamente para todos os tipos de dados, exceto para char. Em vez de incrementar o valor de char, por que não dar a ele um comportamento especial e converter o caractere para maiúsculas?
Para fazer isso, podemos ir para a especialização de modelo para o tipo de dados char.
Esta implementação é mostrada no exemplo de código abaixo.
#include using namespace std; // class template: template class myIncrement { T value; public: myIncrement (T arg) {value=arg;} T toIncrement () {return ++value;} }; // class template specialization: template class myIncrement { char value; public: myIncrement (char arg) {value=arg;} char uppercase () { if ((value>='a')&&(value<='z')) value+='A'-'a'; return value; } }; int main () { myIncrement myint (7); myIncrement mychar ('s'); myIncrement mydouble(11.0); cout<<'Incremented int value: '<< myint.toIncrement()<< endl; cout<<'Uppercase value: '< Resultado:
Valor interno incrementado: 8
Valor em maiúsculas: S
Valor duplo incrementado: 12

No programa acima, que demonstra a especialização do template, veja a maneira como declaramos um template especializado para o tipo char. Primeiro declaramos a classe original e então a 'especializamos' para o tipo char. Para iniciar a especialização, usamos a declaração de template vazia “template”.
Então, após o nome da classe, incluímos o tipo de dados. Após essas duas mudanças, a classe é escrita para o tipo char.
Na função principal, observe que não há diferença entre a instanciação do tipo char e outros tipos. A única diferença é que redefinimos a classe especializada.
Observe que devemos definir todos os membros da classe especializada, embora eles sejam exatamente os mesmos na classe de modelo genérica / original. Isso ocorre porque não temos o recurso de herança para membros do modelo genérico para o modelo especializado.
Modelos C ++ Variadic
Até agora, vimos modelos de função que recebem um número fixo de argumentos. Também existem modelos que aceitam um número variável de argumentos. Esses modelos de função são chamados de modelos variadic. Os modelos variados são um dos recursos mais recentes do C ++ 11.
Os modelos variáveis aceitam um número variável de argumentos que são seguros para o tipo e os argumentos são resolvidos em tempo de compilação.
Vamos dar um exemplo de programação completo para entender isso.
#include #include using namespace std; template T summation(T val) { return val; } template T summation(T first, Args... args) { return first + summation(args...); } int main() { long sum = summation(1, 2, 3, 8, 7); cout<<'Sum of long numbers = '< O exemplo acima demonstra a função variada, “soma”. Conforme mostrado acima, primeiro precisamos de uma função base que implemente o caso base. Em seguida, implementamos a função variadic no topo desta função.
Na soma da função variável, “typename… args” é chamado pacote de parâmetros de modelo enquanto “Args ... args” é chamado pacote de parâmetros de função .
Depois de escrever um modelo de função que implementa o caso base, escrevemos uma função variável que implementa o caso geral. A função variadic é escrita semelhante à recursão conforme mostrado para soma (args…). O primeiro argumento é separado do pacote de parâmetros de função no tipo T (primeiro).
Com cada chamada ao somatório, a lista de parâmetros fica mais estreita em um argumento e, eventualmente, a condição de base é alcançada. A saída mostra a soma de inteiros e caracteres longos.
Conclusão
Com isso, concluímos este tutorial sobre templates em C ++. Os modelos nos ajudam a tornar nossos programas genéricos, ou seja, independentes do tipo.
Leia também = >> Tutorial de modelo de frasco
Os programas genéricos sempre ficam acima dos outros programas, pois não precisamos escrever programas separados para cada tipo de dados. Assim, o desenvolvimento de programas genéricos de tipo seguro pode ser um passo importante para uma programação eficiente.
=> Verifique os tutoriais detalhados de treinamento C ++ aqui.
Leitura recomendada
- Tutorial da função principal do Python com exemplos práticos
- Como funcionam os testes orientados a dados (exemplos de QTP e Selenium)
- Multithreading em C ++ com exemplos
- Tutorial Python DateTime com exemplos
- Modelo de caso de teste de amostra com exemplos de caso de teste (download)
- Cortar comando no Unix com exemplos
- Modelo de amostra para relatório de teste de aceitação com exemplos
- Sintaxe de comando Unix Cat, opções com exemplos