Buenas señores..
Tengo una duda a medias... creo entender como va esto de las plantillas pero quisiera estar seguro.
Del siguiente codigo:
template <typename T>
void my_function ( T _param);
Entiendo que para este caso, T es un tipo generico que acepta cualquier clase de argumento (puntero, referencia o valor)
Como quien dice, no tiene formato, puede ser constante, estatico, etc...
int x = 19;
my_function ( x ); //en la plantilla, T se transformaria en int .... int _param = 19;
int * px = &x;
my_function ( px ); //en la plantilla, T se transformaria en int * .... int * _param = &x;
Como T es virgen (por decirlo de alguna forma), no esta pre-formateada, simplemente es una T sola, puede aceptar cualquier tipo de clase y con cualquier tipo de atributo... es asi?
Pero en este siguiente caso:
template <typename T>
void my_function ( T* _param);
Aqui T es puntero, entiendo que solo acepta una direccion de memoria u otro puntero, pero no un elemento por valor, ya que T* ha sido pre-formateado para funcionar solo como puntero.
int x = 19;
my_function ( x ); //esto produce un error porque x es un tipo, no un puntero....
int * px = &x;
my_function ( px ); //esto estaria bien, ya que seria una asignacion de puntero....
Segun entiendo, en el fondo la asignacion a un tipo plantilla es como si se comportara como override de funcion:
T = Acepta cualquier cosa por valor
T& = Acepta cualquier cosa solo que como referencia
T* = Preformateada para aceptar solo punteros o direcciones de memoria o referencias a punteros
const T = Preformateada para aceptar cualquier cosa por valor pero se transforma obligatoriamente en constante
const T& = Preformateada para aceptar cualquier cosa por referencia pero se transforma en constante
const T* = Preformateada para aceptar solo punteros o direcciones de memoria y lo transforma a constante.
En el siguiente ejemplo:
template <typename T>
void my_function ( const T* _param);
const float * pfloat = new float(12.5f);
my_function ( pfloat ); //esto se asignara bien.
float * pfloat2 = new float (6.9f);
my_function ( pfloat2 ); //esto tendria el mismo efecto que pfloat ya que en la plantilla siempre quedara como const.
Es mas o menos como lo creo?
Saludos
Hola, creo que te facilitará la idea si consideras que en
template <typename T>
void my_function ( T _param);
T es el tipo del parámetro _param, o lo que es lo mismo: "el tipo de _param es T"; como cuando se tiene int i = 5; decimos que el tipo de i es int, o que i es de tipo int. (Fíjate que le he dado la vuelta a la forma en que lo dices).
Cuando se tiene int* p; se dice que p es de tipo int* (Como el C++ está más centrado en tipos que el C, es por eso que se prefiere escribir int* p en lugar de int *p).
En el ejemplo de acá abajo, la función genérica f tiene un parámetro t de tipo T*. Creo que al decirlo de esta manera se percibe más claramente la idea.
#include <iostream>
#include <typeinfo>
template<typename T>
void f(T* t) {
std::cout << "type: " << typeid(t).name() << '\n';
}
int main()
{
int* p = new int(6);
f<int>(p); // en esta funcion el tipo de t es "int*".
f(p); // es lo mismo ("Template argument deduction")
f<int*>(&p); // en esta segunda funcion el tipo de t es "int**"
f(&p); // es lo mismo ("Template argument deduction")
std::string str = "hola";
f(&str);
}