A Coder’s Corner

Blog de tecnologia y programación

Templates de C++ – Una Introducción

Posted by gfaraj on May 1, 2007

Los templates son muy importantes en el desarrollo de software con C++. Es sin duda una de las caracteristicas mas importantes (si no es la mas importante) de este lenguaje. Nos permite escribir codigo generico que puede ser usado con varios tipos de datos. Sin templates, se tendrian que reescribir muchas funciones y clases. Tomemos el siguiente ejemplo de una funcion que retorna el maximo de dos valores.

int max(int x, int y)
{
    return (x < y) ? y : x;
}

float max(float x, float y)
{
    return (x < y) ? y : x;
}

Como podemos ver, sin templates dos funciones que tienen el mismo cuerpo se tienen que reescribir para que funcione con varios tipos. Veamos la misma funcion usando templates.

template <typename T>
T max(T x, T y)
{
    return (x < y) ? y : x;
}

Esta funcion funciona con cualquier tipo que se pueda comparar con el operador <. Funciona hasta con tu propia clase si ella tiene el operador < implementado. Tambien se puede tener templates para clases. Clases como std::vector y std::list son templates y nos permiten usarlas para cualquier tipo que querramos. Veamos un ejemplo de una clase template.

template <typename T>
class Puntero
{
    T* _ptr;

public:
    explicit Puntero(T* ptr = 0) : _ptr(ptr) {}
    ~Puntero() { delete _ptr; }

    // implementamos estos operadores para que la clase actue como puntero
    T& operator*() { return *_ptr; }
    T* operator->() { return _ptr; }
};

int main()
{
    Puntero<int> puntero_int(new int);
    *puntero_int = 10;

    Puntero<bool> puntero_bool(new bool);
    *puntero_bool = true;
}

Ahi podemos ver una clase (incompleta) que trata de personificar un puntero. Cuando se destruye una instancia de esta clase, tambien destruye el puntero que contenia. Ahi pueden ver lo facil que es hacer una clase generica y los beneficios que esto trae. Sin templates, hubiera tenido que copiar la misma clase dos veces, cambiando ‘int’ por ‘bool’ solamente. Ahi se va notando que el reuso del codigo puede ser significativo al usar templates. Imaginense reimplementar std::vector por cada tipo que se quiera usar…

Bueno, esta solo era una pequeña introduccion. Espero que les haya gustado y volvere con algo mas avanzado la proxima.😉

29 Responses to “Templates de C++ – Una Introducción”

  1. wow que bien por fin tengo un poco de idea sobre templates🙂 es que esta es la primera informacion que leo en espanol, todo el tiempo lo veia en ingles, y no sabia como seria la traduccion a espanol, pero veo que no se lo traduce xD

    gracias por el articulo🙂

  2. gfaraj said

    Me alegra que te haya gustado🙂

    La traduccion de la palabra “template” a español seria “plantilla”, pero prefiero mantener la palabra “template” porque asi se muestra en el codigo.

  3. Alexi said

    Hola,

    Quisiera hacer una consulta..

    ¿Como puedes usar los template para paginas web? o como uso C++ para los sitios web

    Gracias

  4. gfaraj said

    Estos templates no tienen nada que ver con los templates de una pagina web (como por ejemplo Smarty para PHP). C++ se puede usar por medio de CGI en un servidor web. Tambien se puede usar para crear controles ActiveX para Internet Explorer. Espero haber respondido tu pregunta.

  5. Dulcinea said

    Genial!!!!…creo que es la explicación mas clara y sencilla que puede haber sobre los templates… buena anotación la de que vale para clases si tienes implementado el operador😉.

    Enhorabuena!!!…

  6. gfaraj said

    Gracias Dulcinea. Me alegra que te halla gustado🙂

  7. Parmaia said

    Buenas, estoy trabajando con templates y al definir mi clase en un .h y la implementacion en un .cpp tengo un error al momento del enlace como si el compilador no consiguiera la implementacion que esta en el .cpp, si lo hago todo en el mismo .h funciona perfecto, cual puede ser la causa?

    Ejemplo:

    MiClase.h

    #ifndef MiClase_H
    #define MiClase_H

    template
    class MiClase{
    public:
    MiClase();
    void Algo(Tipo A);
    };

    #endif

    MiClase.cpp

    #include "MiClase.h"

    template
    MiClase::MiClase(){
    //Nada...
    }

    template
    void MiClase::Algo(Tipo A){
    //Nada...
    }

    main.cpp

    #include "MiClase.h"

    int main(){
    MiClase C;
    C.Algo(5);
    return 0;
    }

    Para compilar:
    g++ MiClase.cpp main.cpp -o Ejecutable

    Error:
    /tmp/cc6XNSRb.o: In function `main’:
    main.cpp:(.text+0x194): undefined reference to `MiClase::MiClase()’
    main.cpp:(.text+0x1a7): undefined reference to `MiClase::Algo(int)’
    collect2: ld devolvió el estado de salida 1

    Gracias de antemano por cualquier comentario al respecto.

  8. Parmaia said

    Perdon, no salieron los < > escribo el ejemplo de nuevo:

    MiClase.h

    #ifndef MiClase_H
    #define MiClase_H

    template <class Tipo>
    class MiClase{
    public:
    MiClase();
    void Algo(Tipo A);
    };

    #endif

    MiClase.cpp

    #include "MiClase.h"

    template <class Tipo>
    MiClase<Tipo>::MiClase(){
    //Nada...
    }

    template <class Tipo>
    void MiClase<Tipo>::Algo(Tipo A){
    //Nada...
    }

    main.cpp

    #include "MiClase.h"

    int main(){
    MiClase<int> C;
    C.Algo(5);
    return 0;
    }

    Para compilar:
    g++ MiClase.cpp main.cpp -o Ejecutable

    Error:
    /tmp/cc6XNSRb.o: In function `main’:
    main.cpp:(.text+0x194): undefined reference to `MiClase<int>::MiClase()’
    main.cpp:(.text+0x1a7): undefined reference to `MiClase<int>::Algo(int)’
    collect2: ld devolvió el estado de salida 1

    Gracias de antemano por cualquier comentario al respecto.

  9. gfaraj said

    @Parmaia:

    Las definiciones de los templates requieren estar disponibles al momento de compilarse. Por esta razon, lo ideal es poner todo en el header (.h). Existe lo que se llama “explicit instantiation,” que permite instanciar un template para un grupo de tipos en especifico (por ejemplo, MiClase<int> y MiClase<float>). Esto permite poner las definiciones en un .cpp, pero otros archivos solo podran usar el template con los tipos especificos con los que fue instanciado explicitamente.

    template class MiClase<int>;
    template class MiClase<float>;

    Otra opcion, es el keyword “export.” El problema aqui es que muy pocos compiladores han implementado esto y la verdad que al final no es muy util. Lo mas practico es definir todo en el .h.

  10. JHAx86 said

    Gracias, en la Wiki de OGRE te mandan a comprar un libro si no sabes lo que son templates. Pero gracias a ti no tengo que perder más tiempo, cosas como éstas enriquecen la web.

    Saludos.

  11. yo said

    Tengo algunas dudas existenciales, no sé si este es el mejor sitio

    Un asterisco delante de una variable es un puntero, hasta aqui ok:

    *puntero_int

    pero detras de un tipo o una variable que es?

    T* operator

    Un ampersand delante de una variable, es un paso por referencia:

    &var_name

    pero detras de un tipo que es?

    T& operator*

    Muchas gracias

  12. leon said

    Eh creo que ya no vas a volver a leer esto, pero por si alguien mas pasa y tiene dudas parecidas no da para dejarlas asi sin contestar =)

    *puntero_int
    no es un puntero, el puntero es “puntero_int” (una variable de tipo puntero). El * delante de una variable se pude leer como “valor apuntado por”. Te queda “valor apuntado por puntero_int”.

    T* puntero
    Eso define un puntero a algo de tipo T. El * despues de un nombre de tipo es como decir “puntero a”. T* se lee como “puntero a T” y es un tipo de variable.

    &var_name
    El & delante de un nombre de variable NO es una referencia, es la direccion de memoria del contenido de var_name. Por decirlo sin mucha “correctancia”, te devuelve un puntero a la variable. Se podria leer como “puntero a”. Te queda “puntero a var_name” (lo mas correcto es leerlo como “direccion de”). Creo que & usado asi se llama “operador de indireccion”, pero no me juego a ello.

    T&
    El & despues de un tipo de variable quiere decir, ahora si, que es una referencia. En este caso quiere decir que el operador te devuelve una referencia a algo de tipo T (el contenido del puntero):
    T& operator*() { return *_ptr; }

  13. Julio said

    Es la mejor explicacion de templates que vi en mi vida, y eso que lei un monton por que cuando las vi por primera vez no las podia entender ni un poquitin!

    gfaraj sos un maestro! gracias!

  14. Clelia said

    Que buena informacion has publicado en este blog!!! Esta explicado de forma sumamente sencilla.

    Muchas gracias, continua asi.

  15. carlos said

    excelente…. gracias por las explicaciones… todas son muy utiles!

  16. ozz1 said

    como podria reimplementar std::pair para un solo tipo de dato;

    • gfaraj said

      @ozz1, no estoy seguro si entiendo lo que estas preguntando, pero talvez es esto:

      template <typename T>
      struct hg_pair
      {
      T first;
      T second;
      };

      Gracias por todos los comentarios.

  17. harold said

    gracias por el tutorial aver si me agregas al msn

  18. Ariel said

    Muchísimas Gracias, realmente valoro mucho personas como vos que se toman un tiempo para compartir y enseñar!! Muchas Gracias..

  19. ashley said

    quiero aser un juego todos me disen que lo puedon aser pero el problema es que no se como aserlo si ai alguiem que me pueda esplicar porfa diganme

  20. ashley said

    alguiencomo se ase un juegos me puede esplicar

  21. It’s hard to come by well-informed people in this particular topic, however, you seem like you know what you’re talking about! Thanks

  22. I’m curious to find out what blog platform you have been utilizing? I’m having some small security issues with my latest blog and I would like to find something more safe. Do you have any suggestions?

  23. For most up-to-date news you have to go to see the web and on web I
    found this web site as a finest website for latest updates.

  24. HolaMundo xD said

    Hola quisiera saber: ¿cuál es la sintaxis para algo como “nombreDeLaClase<nombreDeOtraClase>”, o sea para un template que recibe como parametro otro template?
    Muchas gracias de antemano…

    • HolaMundo xD said

      Disculpen es “nombreDeLaClase<nombreDeOtraClase>”…

      • HolaMundo xD said

        jajajajajajajajaja… que madre… aquí también tiene un choque de sintaxis como en c++ … xD la idea era un template que recibe como tipo otro template…

  25. In the online education programs, almost all the subjects are includes, such as; literature, pharmacy, doctor,
    MBA, Engineering. A student can now achieve education through the
    Internet from the comfort of his or her home.

    One can visit any of the directories and can get information about
    online accredited colleges.

  26. It’s a pity you don’t have a donate button! I’d without a doubt donate to this outstanding blog!

    I suppose for now i’ll settle for book-marking and adding your RSS feed to my Google account.
    I look forward to new updates and will talk about this website with my Facebook group.

    Talk soon!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: