Talking about templates could lead to a record as the longest response from StackOverflow, so I will only limit myself to a simple introduction.
Templates are generic objects, it's like a mold from which to create objects with particular characteristics.
In the following example we created a class with a member named dato
:
template<class T>
struct Wrapper
{
T dato;
};
What type is data? so first of none. The type will be determined when we go to instantiate an element from the template:
int main()
{
Wrapper<int> varInt; // dato sera de tipo int
Wraper<std::string> varStr; // dato sera de tipo string
varInt.dato = 5; // ok
// varInt.dato = "abcd"; // ERROR, dato es de tipo int
// varStr.dato = 5; // ERROR, dato es de tipo string
varStr.dato = "abcd"; // ok
std::cout << varInt.dato << ' ' << varStr.dato;
}
The previous example, without applying templates, would look like this:
struct WrapperInt
{
int dato;
};
struct WrapperStr
{
std::string dato;
};
int main()
{
WrapperInt varInt; // dato sera de tipo int
WraperStr varStr; // dato sera de tipo string
varInt.dato = 5; // ok
// varInt.dato = "abcd"; // ERROR, dato es de tipo int
// varStr.dato = 5; // ERROR, dato es de tipo string
varStr.dato = "abcd"; // ok
std::cout << varInt.dato << ' ' << varStr.dato;
}
It seems more or less obvious that it is preferable to use a template than having to repeat the same implementation for different data types. For the example that I have given you the advantage would not be too big, but imagine that you implement a list of data Would you like to know that you have to do 10 (or 20) different versions of the list with the same code but only changing the types? (one for int
, another for float
, as many for structures that you use in your application ...) I think you explain.
The restrictions when indicating the type in a template is that the resulting code must be compilable:
template<class T>
void Print(T dato)
{ std::cout << dato; }
struct MiStruct
{
int id;
};
int main()
{
Print(5); // ok, el operador << de std::cout tiene una sobrecarga para el tipo int
MiStruct a;
Print(a); // ERROR, no hay una sobrecarga del operador << valida
}
Thus, when designing a template, it is important to be aware that certain elements are not of a specific type of data. This concept is difficult to understand at the beginning and it is necessary to go into work to get to understand it well.
And what does that mean of class T
?
class T
is used to indicate the generic types. Actually T
is just an identifier that we give to one of the types. You can really use the identifier you want, so try to make the chosen names representative:
// Esta funcion convierte una variable de tipo 'Tipo1' en otra de tipo 'Tipo2'
template<class Tipo1, class Tipo2>
Tipo1 Convertir(Tipo2 t)
{
return static_cast<Tipo1>(t);
}
// Ejemplo de uso
char c = Convertir<char>(70); // Convierte de int a char
std::cout << c; // Imprime la letra F
With this information you already have more or less enough to do what they ask you to do. I would attack the problem in the following way:
Create a class (not template) that meets the request in practice that works with int
.
Do tests to verify correct operation
Add template<class T>
or template<typename T>
(it's indifferent) to the class and start replacing (where appropriate) int
by T
.
Doubts that may arise in SOes questions.