Anuncios

Bienvenidos sean a este post, hoy veremos como utilizar template de otra manera.

Anuncios

En este post vimos que es un template y como nos permite tener tipos genericos para una clase y en esta poder trabajar con distintos tipos en la misma.

Anuncios

Esto fue una solucion alternativa al uso de sobrecarga en funciones, metodos para las clases, para poder procesar distintos tipos de datos en una misma funcion. Pero como indica el titulo, esta misma mecanica la podemos aplicar a las funciones comunes que no pertenezcan a una clase. Veamos como es su sintaxis:

template <class id1, class id2,..., class idN>
idx nombre_funcion(idx argumentos) { ... 
Anuncios
template <typename id1, typename id2,...,typename idN>
idx nombre_funcion(idx argumentos) { ... 
Anuncios
Anuncios

Es muy similar a lo que vimos en template para clases. Primero lo establecemos con un identificador pero en esta ocasion podemos usar tanto a class como typename. Este ultimo esta pensado para manejar tipos que no sean clases, como los tipos primitivos, pero en la actualidad se mantiene mas por un tema de compatibilidad, ya veremos el porque. Por otro lado, podemos usar todos los identificadores que necesitemos, como sucedia cuando usabamos a template y map donde utilizabamos dos, y el que usemos sera para el tipo que manipulara la funcion. Dando la posibilidad de poder usar cualquier tipo. Para entender el concepto, vamos a analizar el siguiente ejemplo:

#include <iostream>

int sumar(int a, int b)
{
        return a + b
}

int main()
{
        double a = 11.11;
        double b = 22.22;
        int c = 12;
        int d = 23;
        std::cout << "Double: " << sumar(a,b) << std::endl;
        std::cout << "Int: " << sumar(c, d) << std::endl;

        return 0;
}
Anuncios

Primero definiremos una funcion que recibira dos valores de tipo int y devolvera la suma de ambos y el mismo tipo. En el main, definiremos cuatro variables con distintos valores. Siendo dos de tipo double y las otras de tipo int. Para finalmente, pasarlas a la funcion y ver cual es el resultado. Compilemos y veamos como es la salida:

$ ./func
Double: 33
Int: 35
$
Anuncios

Si bien, hoy en dia si tenemos valores numericos, el compilador los convertira internamente para poder manejarlos pero no hace lo que solicitamos. Porque no tenemos el valor en double. Al codigo anterior, agreguemos a la siguiente funcion:

double sumar(double a, double b)
{
        return a + b;
}
Anuncios

Es una simple sobrecarga de la funcion que existe, no importa si lo agregan antes o despues de la otra funcion, pero si debe estar antes del main. El resto sigue siendo el mismo codigo, compilemos y veamos como es la nueva salida:

$ ./func
Double: 33.33
Int: 35
$
Anuncios

Como pueden ver ahora si nos devolvio los valores que deseabamos tener porque hay una funcion para manejar a cada tipo de dato. Podemos agregar mas para controlar mas tipos. Pero esto lo podemos mejorar. Modifiquemos el codigo anterior de la siguiente manera:

#include <iostream>

template <class T>
T sumar(T a, T b)
{
        return a + b;
}

int main()
{
        double a = 11.11;
        double b = 22.22;
        int c = 12;
        int d = 23;
        std::cout << "Double: " << sumar<double>(a,b) << std::endl;
        std::cout << "Int: " << sumar(c, d) << std::endl;

        return 0;
}
Anuncios
Anuncios

Primer cambio, eliminamos las dos funciones. Segundo cambio, usamos la misma pero con el template y el tipo que usamos se asignara a la misma. La funcion hace exactamente lo mismo. El resto sigue siendo igual, salvo por como llamamos a la funcion. La primera se la denomina como Explicita, donde le informamos cuales son los tipos que debe manejar. En el segundo caso, se la denomina como implicita donde trabajara en base a los tipos que recibe. Si lo compilan y ejecutan deben obtener la misma salida que vimos anteriormente. Pero esto no significa que no podemos hacer una sobrecarga para este tipo de funciones. Tomemos el caso anterior y hagamos la siguiente modificacion:

#include <iostream>
#include <string>

template <class T>
T sumar(T a, T b)
{
        return a + b;
}
template <>
std::string sumar<std::string> (std::string a, std::string b)
{
        std::cout << " - se llamo a la sobrecarga - " << std::endl;
        std::cout << "String: ";
        return a + b;
}

int main()
{
        double a = 11.11;
        double b = 22.22;
        int c = 12;
        int d = 23;
        std::string e = "Hola, ";
        std::string f = "Mundo!";
        std::cout << "Double: " << sumar(a,b) << std::endl;
        std::cout << "Int: " << sumar(c, d) << std::endl;
        std::cout << sumar(e, f) << std::endl;

        return 0;
}
Anuncios
Anuncios

Si bien este cambio no es necesario, porque funciona igualmente, lo hacemos para ejemplificar dos temas como la especificacion y la sobrecarga. La nueva funcion es una sobrecarga de la funcion generica pero la especificamos para que maneje unicamente datos de tipo string. La primera curiosidad es que antes de la misma usamos un template sin ningun valor. Esto es para poder respetar la firma de la funcion generica y poder sobrecargarla. En el cuerpo de esta mostraremos un mensaje para indicar que fue utilizada y otro para indicar que es una string y por ultimo devolvemos el dato resultante de concatenar ambos valores. El resto sigue de igual forma. Pero incluiremos a la libreria encargada de manejar los tipo string asi como taambien definiremos dos variables con informacion para poder pasarla a la funcion sumar y mostrar el resultado final. Compilemos y veamos como es la salida:

$ ./func
Double: 33.33
Int: 35
 - se llamo a la sobrecarga -
String: Hola, Mundo!
$
Anuncios

Aca podemos observar como se llamo a la funcion sobrecargada al momento de utilizar el tipo de dato string. A pesar de lo comentado al principio, no seria necesario porque haria lo mismo pero lo utilizamos igualmente para ver como trabaja. Al igual que vimos con las clases, utilizar templates en funciones aunque podemos denominarlas como funciones genericas, nos facilitan las tareas y especialmente podemos evitar el uso de sobrecargas de una funcion para multiples tipos de datos. Y seguir usando estas tecnicas para ser mas especificos.

Anuncios

En resumen, hoy hemos visto template de funciones, que es, para que sirve, como se aplica, un ejemplo en que nos puede beneficiar, y como mantener una mecanica a pesar de ser reemplazada. Espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donatión

It’s for site maintenance, thanks!

$1.50