Publicado el 3 de Mayo del 2017
781 visualizaciones desde el 3 de Mayo del 2017
40,1 KB
3 paginas
Creado hace 13a (07/07/2011)
Plantillas
Juan Hernando Vieites
Declaraciones de plantilla
Tipos de declaraciones vistas hasta ahora:
Variable: tipo identificador;
tipo identificador(arg1, arg2, ...);
Funcin: tipo_retorno identificador ( tipo1 arg1,
tipo2 arg2, ...);
Clase:
class identificador { };
Una declaracin de plantilla es una declaracin de funcin o clase
genØrica, es decir, en la algunos elementos de la declaracin se
sustituyen por parÆmetros genØricos.
La sintaxis usa la palabra reservada template:
template<lista de parÆmetros> declaracin;
Declaraciones de plantilla
Declaraciones de plantilla
Las listas de parÆmetros son listas separadas por comas de:
Declaracin de funciones de plantilla:
Un identificador para un tipo: usando las palabras
reservadas class o typename y opcionalmente un valor por
defecto
typename id
typename id = tipo
class id
class id = tipo
ej. typename T
ej. typename T = int
ej. class Elemento
ej. class Elemento = std::string
Un tipo concreto, y un valor por defecto opcional
tipo id
tipo id = valor_por_defecto
ej. int x
ej. int x = 10
Los parÆmetros con valores por defecto siempre van al final de
la lista y no pueden usarse en declaraciones de funcin
template <typename T>
BIEN
void suma(T a, T b);
template <typename T, class U>
U transforma(T x); BIEN
template <typename T, typename U, int m>
void insertar(T &lista, U valor); BIEN
template <typename T = int>
void f(T x); MAL
template <typename T = int, typename U>
void g(T t, U u);
MAL
Declaraciones de plantilla
Declaraciones de plantilla
Declaracin de clases de plantilla:
template <typename T>
class MiClase {
public:
void asignar(const T &);
T t;
};
BIEN
template <typename Tipo1>
class ClaseConFuncionDePlantilla {
public:
template<typename Tipo2> void funcion(Tipo2 x);
Tipo1 atributo;
};
BIEN
Declaracin de clases de plantilla:
template <typename T, int elementos = 10>
class Vector {
public:
const T &operator[](unsigned int i);
protected:
T _vector[elementos];
};
template <typename T, T valor_inicial = 0>
struct Puntero {
Puntero() : _puntero(valor_inicial) {}
T *_puntero;
BIEN
};
BIEN
Definicin de plantillas
Definicin de plantillas
El cuerpo de una clase o funcin de plantilla se define igual que que
Cuando las declaraciones se separan la sintaxis a emplear en las
en una clase o funcin normal.
El compilador no genera cdigo objecto para una plantilla hasta el
momento en el que se instancia (explicado a continuacin).
Por portabilidad, lo aconsejable es organizar el cdigo de alguna de las
siguientes maneras:
Incluir las definiciones siempre junto a las declaraciones.
Escribir las definiciones separadas de las declaraciones pero en el
mismo fichero.
Escribir las definiciones en otro fichero pero incluirlo desde el
fichero de las declaraciones con la directiva #include
Con definiciones separadas es muy aconsejable usar el
modificador inline en la declaracin (ejemplos mÆs adelante).
definiciones es la siguiente:
Para funciones:
template<X x, Y y, ...>
tipo_retorno identificador_funcion(parametros)
{
...
}
Para funciones miembro de clases (mØtodos):
template<X x, Y y, ...>
tipo nombre_clase<X, Y>::nombre_miembro(parametros)
{
}
Definicin de plantillas:
Definicin de plantillas:
ejemplos
Definiciones y declaraciones juntas:
template <typename T>
T suma(const T &a, const T &b)
{
return a + b;
Definiciones y declaraciones
separadas:
}
template <typename T>
class Vector
{
public:
};
}
T *_datos;
const T &operator[ ](unsigned int i)
{
return datos[i];
Definicin de plantillas:
ejemplos
Definiciones y declaraciones separadas:
template <typename T>
class Vector
{
public:
inline const T &operator[ ](unsigned int i);
T *_datos;
};
template <typename T>
const T &Vector<T>::operator[ ](unsigned int i)
{
return _datos[i];
}
ejemplos
Definiciones y declaraciones separadas:
template <typename T>
inline T suma(const T &a, const T &b);
template<typename T>
T suma(const T &a, const T &b)
{
return a + b;
}
Instanciacin de plantillas
Una plantilla se instancia cuando se da un valor concreto a sus
parÆmetros. La instanciacin puede ser:
Explcita, se da valor a los parÆmetros uno a uno.
Se da tpicamente cuando se declara una variable de una
clase de plantilla:
template<typename T> class A ...; // Declaracin
A<int> a; // Instanciacin explcita para declarar a
Implcita, tambiØn llamada deducida. El compilador trata de
encontrar los valores mÆs apropiados para cada parÆmetro
y si no los encuentra da un error.
template<typename T> void funcion(T t); // Declaracin
funcion(10); // Instanciacin implcita como int
Instanciacin de plantillas
Instanciacin de plantillas
En el momento de instanciar una plantilla es cuando el
compilador genera cdigo para ella, siempre y cuando no se
hubiese instanciado ya en esa unidad de compilacin y para los
parÆmetros de instanciacin.
Hasta la instanciacin no se hace comprobacin semÆntica del
cdigo, slo sintÆctica. Esto significa que:
Muchos errores de codificacin no aparecen hasta que la
plantilla se instancia.
Para las clases de plantilla algunos errores no se detectan
hasta que se utiliza la funcin que contiene cdigo errneo.
Que una plantilla compile no quiere decir que sea correcta si
no se usa.
La principal debilidad de las plantillas que los errores de compilacin son
oscuros y crpticos, a veces son difciles de interpretar incluso para un
programador de C++ experto, sobre todo con bibliotecas de plantillas.
Un ejemplo de error:
std::vector<float> x;
std::vector<int> y;
x = y;
Produce:
/tmp/prueba.cpp: In function ’int main()’:
/tmp/prueba.cpp:16: error: no match for ’operator=’ in ’x = y’
/usr/include/c++/4.3/bits/vector.tcc:144: note: candidates are: std::vector<_Tp, _Alloc>&
std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = float, _Alloc
std::allocator<float>]
=
Consejo: Si el error es muy confuso, no intentar entenderlo, mejor ir a la
lnea que lo ha producido al instanciar la plantilla y verificar que la sintaxis
es correcta y los valores usados son vÆlidos.
Comentarios de: Plantillas (bw) (0)
No hay comentarios