Templates em C++
Uma das coisas mais estranhas do C++ pra mim são os templates, a sua sintaxe não é lá muito intuitiva (mas já vi coisas piores). Mas os templates são importantes, na verdade foram graças aos templates em C++ que a programação genérica se fortaleceu.
Um template lembra um define, só que bem mais “parrudo” e seguro. Imagine que você tenha duas funções que some dois números cada, a primeira função serve para somar dois números inteiros e a segunda soma dois números de ponto flutuante.
int soma_int(int a, int b) { return (a + b); } float soma_float(float a, float b) { return (a + b); } soma_int(10, 20); // retorna 30 soma_float(10.12, 20.34); // retorna 30.46
Com os templates é possível criar uma única função que some estes números mesmo que sejam de tipos diferentes de dados.
Basicamente para se criar uma função template é preciso ter a seguinte sintaxe:
template <class identificador> declaração_da_função;
Utilizando o template no código anterior ele ficaria assim:
template <class T> T soma(T a, T b) { return (a + b); } soma<int> (10, 20) // retorna 30 soma<float> (10.12, 20.34); // retorna 30.46
O código ficou menor, pois eu só precisei criar uma função. Com uma explicação bem tosca eu poderia dizer que o compilador troca todos os "T" da função template pelo que estiver entre os sinais de maior e menor na hora que você chama a função (soma<int>, soma<float>). É parecido com o define, porém os templates possuem checagem de tipagem de dados, são bem mais versáteis e evitam que se cometam erros bobos com o uso de defines em excesso.
Se os parâmetros da função são de apenas 1 tipo não é necessário especificar com o <int> ou <float>, o compilador já deduz o tipo:
soma(10, 20) // OK, os dois parâmetros são int soma(10.12, 20.34); // OK, os dois parâmetros são float soma(10, 20.34) // ERROR, os dois parâmetros são de tipos diferentes
Você também pode especificar mais tipos para o template:
template <class TValue, class TPercent, class TReturn> TReturn get_percentage(TValue value, TPercent percentage) { return (TReturn)(value * (percentage / 100.0)); } get_percentage<int, float, int>(1000, 80.33) // retorna 80.33% de 1000 como int (803) get_percentage<int, float, float>(1000, 80.33) // retorna 80.33% de 1000 como float (803.3)
Para deixar claro: "função<tipo1, tipo2, tipoN> (...);" corresponde a "template <class tipo1, class tipo2, class tipoN...> função(...);".
É possível utilizar os templates em classes também:
template <class T> class my_class { private: T attr; public: my_class (T value) { attr = value; } }; my_class<int> object(1); // instânciando
Fiz uma explicação bem simples sobre o uso de templates, mas existem mais coisas que você deve aprender jovem Padawan. Recomendo uma lida aqui cplusplus.com e aqui Universal Knowledge Center About Everything.


muito bom
Cara eu nunca tinha entendido os templates, mas graças ao teu artigo foi bem fácil, valeu mesmo!