templates : T y T*

Iniciado por digimikeh, 5 Octubre 2021, 05:24 AM

0 Miembros y 1 Visitante están viendo este tema.

digimikeh

Buenas señores..

Tengo una duda a medias... creo entender como va esto de las plantillas pero quisiera estar seguro.

Del siguiente codigo:
Código (cpp) [Seleccionar]
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...

Código (cpp) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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.

Código (cpp) [Seleccionar]
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:
Código (cpp) [Seleccionar]
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
Dungeons & dragons;
dragons.Attack();

Loretz

Hola, creo que te facilitará la idea si consideras que en

Código (cpp) [Seleccionar]
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.

Código (cpp) [Seleccionar]
#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);
}