Академический Документы
Профессиональный Документы
Культура Документы
Junio 2014
Introduccin
Ventajas
Inconvenientes
Cundo utilizar plantillas?
Qu debo poner en las .hpp y .cpp
Convencin de notaciones
Algunas plantillas conocidas
STL
BGL
Trabajar con plantillas
Especificaciones de plantillas
Plantilla por defecto
Obtener los parmetros de plantilla, tipos y mtodos estticos de una clase-plantilla
Templates recurrentes
Testear valores de tipo plantilla
Enlaces utiles
Introduccin
Las plantillas (Templates) son uno de los grandes aportes de C++ al lenguaje C. Hasta antes de
las plantillas, se pasaban variables como parmetros de las funciones. Gracias al concepto de
plantilla, es posible pasar tipos como parmetros, y de este modo definir funciones genricas.
Pero el concepto de plantillas no se limita a las funciones, tambin puede ser utilizado en clases
y estructuras.
Ventajas
El inters de las plantillas residen en: -la generalizacin: desde el momento en que el tipo
incluye todo lo que es utilizado en la funcin o clase-plantilla, es posible pasar cualquier tipo
como parmetro. -simplicidad: nicamente se codifica una funcin o clase sin importar el tipo
pasado como parmetro, lo que hace que el mantenimiento del cdigo sea ms fcil.
Inconvenientes
-Como lo veremos a continuacin, el uso de plantillas requiere tomar algunas precauciones
Convencin de notaciones
Los parmetros de plantillas son generalmente escritos en maysculas (mientras que los otros
tipos son generalmente escritos en minscula). En la prctica, podemos escribirlos como
queramos. Personalmente los escribo precedidos de una T (por ejemplo Tgraph para designar
un parmetro de plantilla que representa un grafo). Esto puede parecer intil pero veremos que
es muy prctico con los typenames ya que vuelve el cdigo ms legible.
BGL
La BGL (Boost Graph Library) proporciona clases de grafo genricos y los algoritmos
correspondientes (algoritmo del camino ms corto, algoritmo de flot). Para hacerse una idea
del contenido de la BGL, hacer clic en el siguiente enlace.
http://www.boost.org/doc/libs/1_35_0/libs/graph/doc/table_of_contents.html Esta no esta
presente por defecto pero se instala fcilmente. Por ejemplo bajo Debian:
aptitude install libboost-graph-dev
// Un operador-plantilla
template <typename T>
std::ostream & operator<<(std::ostream & out,const my_vector_t<T> & v){
unsigned n = v.size();
out << "[ ";
for(unsigned i=0;i<n;<gras>i) out << v[i] << ' ';
out << ']';
return out;
}
//----------------------- fin my_vector_t.hpp
// Una funcin-plantilla
template <typename T>
void escribir(const my_vector_t<T> & v){
unsigned n = v.size();
std::cout << "[ ";
for(unsigned i=0;i<n;<gras>i) std::cout << v[i] << ' ';
std::cout << ']';
}
int main(){
my_vector_t<int> v(5); // un vector de 5 enteros
v[0] = 6; v[1] = 2; v[2] = 3; v[3] = 4; v[4] = 8;
escribir<int>(v); // llamado a la funcin template
std::cout << std::endl;
escribir(v); // llamado implcito de escribir<int>
std::cout << std::endl;
std::cout << v << std::endl; // llamado al operador template
return 0;
}
Al ejecutar:
[62348]
[62348]
[62348]
Todo lo que est entre inicio clase my_vector_t" y "fin clase my_vector_t" podra ser desplazado
a un encabezado (por ejemplo my_vector.hpp) luego ser incluido por el programa principal.
Especificaciones de plantillas
Nada impide que se implemente especficamente una clase o funcin para un conjunto de
parmetros de plantilla. Notemos que no es necesario especificar todos los parmetros de
plantilla. Partiendo del ejemplo precedente:
#include "my_vector.hpp"
// Una especificacin de plantilla
void escribir(const my_vector_t<int> & v){
unsigned n = v.size();
std::cout << "{ ";
for(unsigned i=0;i<n;<gras>i) std::cout << v[i] << ' ';
std::cout << '}';
}
int main(){
my_vector_t<int> v(5); // un vector de 5 enteros
v[0] = 6; v[1] = 2; v[2] = 3; v[3] = 4; v[4] = 8;
escribir<int>(v); // invoca a la funcin template
std::cout << std::endl;
escribir(v); // invoca a escribir (prevalece a la invocacin implcita de escribir<int>)
std::cout << std::endl;
std::cout << v << std::endl; // invoca el operador template
return 0;
}
Al ejecutarlo:
[62348]
{62348}
[62348]
std::set<int> s;
std::set<int,std::less<int> > s_;
Templates recurrentes
Es posible definir plantillas recurrentes. Un ejemplo:
#include <iostream>
template <int N>
int fact(){
return N*fact<N-1>();
}
template <>
int fact<0>(){
return 1;
}
int main(){
std::cout << fact<5>() << std::endl;
return 0;
}
Aqu el inters es bastante moderado ya que concretamente se compila fact<5>, fact<4>...
fact<0>, es justo para dar un ejemplo simple de template recurrente.
Enlaces utiles
Presentacin de la STL (Standard Template Library): ofrece numerosos contenedores de