» » Curso De C++ - Capitulo 40

Curso De C++ - Capitulo 40

Funciones que usan plantillas como parámetros

Es posible crear funciones que admitan parámetros que sean una plantilla. Hay dos modos de pasar las plantillas: se puede pasar una instancia determinada de la plantilla o la plantilla genérica.

 
Pasar una instancia de una plantilla

Si declaramos y definimos una función que tome como parámetro una instancia concreta de una plantilla, esa función no estará disponible para el resto de las posibles instancias. Por ejemplo, si creamos una función para una tabla de enteros, esa función no podrá aplicarse a una tabla de caracteres:
// F_Tabla.cpp: ejemplo de función de plantilla para 
// Tabla para enteros:
// Mayo 2015 Tutoriales En Linea

#include <iostream>
#include "Tabla.h"
 
using namespace std;
 
const int nElementos = 5;

void Incrementa(Tabla<int> &t); // (1)

int main() {
   Tabla<int> TablaInt(nElementos);
   Tabla<char> TablaChar(nElementos);

   for(int i = 0; i < nElementos; i++) {
      TablaInt[i] = 0;
      TablaChar[i] = 0;
   }

   Incrementa(TablaInt);
   // Incrementa(TablaChar); // <-- Ilegal (2)

   for(int i = 0; i < nElementos; i++)
      cout << "TablaInt[" << i << "] = " 
           << TablaInt[i] << endl;

   return 0;
}

void Incrementa(Tabla<int> &t) { // (3)
   for(int i = 0; i < t.NElementos(); i++)
      t[i]++;
} 
En (1) vemos que el argumento que especificamos es Tabla<int>, es decir, un tipo específico de plantilla: una instancia de int. Esto hace que sea imposible aplicar esta función a otros tipos de instancia, como en (2) para el caso de char, si intentamos compilar sin comentar esta línea el compilador dará error. Finalmente, en (3) vemos cómo se implementa la función, y cómo se usa el parámetro como si se tratase de una clase corriente.

Pasar una plantilla genérica

Si declaramos y definimos una función que tome como parámetro una instancia cualquiera, tendremos que crear una función de plantilla. Para ello, como ya hemos visto, hay que añadir a la declaración de la función la parte template<class T>.
Veamos un ejemplo:
// F_Tabla2.cpp: ejemplo de función de plantilla 
// Tabla genérica:
// C con Clase: Marzo de 2002

#include <iostream>
#include <cstdio>
#include "Tabla.h"
#include "CCadena.h"
 
using namespace std;
 
const int nElementos = 5;

template<class T>
void Mostrar(Tabla<T> &t); // (1)

int main() {
   Tabla<int> TablaInt(nElementos);
   Tabla<Cadena> TablaCadena(nElementos);
   char cad[20];

   for(int i = 0; i < nElementos; i++) TablaInt[i] = i;
   for(int i = 0; i < nElementos; i++) {
      sprintf(cad, "Cad no.: %2d", i);
      TablaCadena[i] = cad;
   }

   Mostrar(TablaInt);    // (2)
   Mostrar(TablaCadena); // (3)

   return 0;
}

template<class T>
void Mostrar(Tabla<T> &t) { // (4)
   for(int i = 0; i < t.NElementos(); i++)
      cout << t[i] << endl;
} 
En (1) vemos la forma de declarar una plantilla de función que puede aplicarse a nuestra plantilla de clase Tabla. En este caso, la función sí puede aplicarse a cualquier tipo de instancia de la clase Tabla, como se ve en (2) y (3). Finalmente, en (4) vemos la definición de la plantilla de función.

 
Amigos de plantillas

Por supuesto, en el caso de las plantillas también podemos definir relaciones de amistad con otras funciones o clases. Podemos distinguir dos tipos de funciones o clases amigas de plantillas de clases:

 
Clase o función amiga de una plantilla

Tomemos el caso de la plantilla de función que vimos en el apartado anterior. La función que pusimos como ejemplo no necesitaba ser amiga de la plantilla porque no era necesario que accediera a miembros privados de la plantilla. Pero podemos escribirla de modo que acceda directamente a los miembros privados, y para que ese acceso sea posible, debemos declarar la función como amiga de la plantilla.

Modificación de la plantilla Tabla con la función Mostrar como amiga de la plantilla:
// Tabla.h: definición de la plantilla tabla:
// Mayo 2015 Tutoriales En Linea

#ifndef T_TABLA
#define T_TABLA

template <class T> class Tabla; // Declaración adelantada de Tabla
template <class T> void Mostrar(Tabla<T> &t); // Para poder declarar la función Mostrar

template <class T>
class Tabla {
  public:
   Tabla(int nElem);
   ~Tabla();
   T& operator[](int indice) { return pT[indice]; }
   const int NElementos() {return nElementos;}

   friend void Mostrar<>(Tabla<T>&); // (1) Y poder declararla como amiga de Tabla

  private:
   T *pT;
   int nElementos;
};

// Definición:
template <class T>
Tabla<T>::Tabla(int nElem) : nElementos(nElem) {
   pT = new T[nElementos];
}

template <class T>
Tabla<T>::~Tabla() {
   delete[] pT;
}
#endif
Programa de ejemplo:
// F_Tabla2.cpp: ejemplo de función amiga de 
// plantilla Tabla genérica:
// Mayo 2015 Tutoriales En Linea

#include <iostream>
#include <cstdio>
#include "Tabla.h"
#include "CCadena.h"
 
using namespace std;
 
const int nElementos = 5;
 
template<class T>
void Mostrar(Tabla<T> &t);  // (2)

int main() {
   Tabla<int> TablaInt(nElementos);
   Tabla<Cadena> TablaCadena(nElementos);
   char cad[20];

   for(int i = 0; i < nElementos; i++) TablaInt[i] = i;
   for(int i = 0; i < nElementos; i++) {
      sprintf(cad, "Cad no.: %2d", i);
      TablaCadena[i] = cad;
   }

   Mostrar(TablaInt);
   Mostrar(TablaCadena);

   return 0;
}

template<class T>
void Mostrar(Tabla<T> &t) { // (3)
   for(int i = 0; i < t.nElementos; i++)
      cout << t.pT[i] << endl;
} 
 
Nota (1): aunque esto no sea del todo estándar, algunos compiladores, (sin ir más lejos los que usa Dev-C++), requieren que se incluya <> a continuación del nombre de la función que declaramos como amiga, cuando esa función sea una plantilla de función. Si te fijas en (2) y (3) verás que eso no es necesario cuando se declara el prototipo o se define la plantilla de función. En otros compiladores puede que no sea necesario incluir <>, por ejemplo, en Borland C++ no lo es. 

Clase o función amiga de una instancia de una plantilla

Limitando aún más las relaciones de amistad, podemos declarar funciones amigas de una única instancia de la plantilla.

Dentro de la declaración de una plantilla podemos declarar una clase o función amiga de una determinada instancia de la plantilla, la relación de amistad no se establece para otras posibles instancias de la plantilla. Usando el mismo último ejemplo, pero sustituyendo la línea de la declaración de la clase que hace referencia a la función amiga:
template<class T>
class Tabla {
   ...
   friend void Mostrar<>(Tabla<int>&);
   ...
}; 
Esto hace que sólo se pueda aplicar la función Mostrar a las instancias <int> de la plantilla Tabla. Por supuesto, tanto el prototipo como la definición de la función "Mostrar" no cambian en nada, debemos seguir usando una plantilla de función idéntica que en el ejemplo anterior.

Deja un comentario

Información
Atención! Usuarios que están en este grupo no pueden dejar comentarios en la página...Primero debes Registrarse!

Redes Sociales

Cómo publicar videos más largos en tus historias de Instagram

Cómo publicar videos más largos en tus historias de Instagram

Si a veces subes videos a tus historias de Instagram , probablemente te has topado con el límite de 15 segundos. Eso significa que no importa la duración del video que publiques en tu historia, Instagram lo recortará automáticamente a una duración máxima de 15 segundos. Esto es ideal para videos...
Recupera Tus Mensajes O Chats De WhatsApp Borrados

Recupera Tus Mensajes O Chats De WhatsApp Borrados

  Recuperar mensajes y chats borrados de tu aplicación WhatsApp para Android es una tarea que puede resultar  necesaria alguna vez. A menudo, estamos tratando de liberar espacio físico de nuestro dispositivo Android y llegamos incluso a borrar...
Integrar El Boton de Whatsapp En Tu Web

Integrar El Boton de Whatsapp En Tu Web

  De todos es conocido que WhatsApp se ha convertido en una herramienta para compartir fotos y vídeos con tus amigos, familiares y compañeros de trabajo. También cada vez más usado, para compartir enlaces de contenidos de la web y otras aplicaciones móviles. Para ayudar a compartir los contenidos...
Crees que las redes sociales te están haciendo bien o mal

Crees que las redes sociales te están haciendo bien o mal

Las redes sociales te ofrecen una forma única de observar a la gente. Por ejemplo, el lenguaje utilizado en Twitter puede usarse para predecir si alguien está en riesgo de morir de una enfermedad cardíaca. El análisis de las actualizaciones de Facebook muestra que las mujeres son generalmente más...
Crea una imagen para las redes sociales

Crea una imagen para las redes sociales

Aprenda a combinar una foto, texto y material gráfico en Photoshop para su Facebook, Twitter y otras publicaciones en redes sociales. Utilice estas habilidades para crear sus propias imágenes de redes sociales o cualquier diseño que cree en Photoshop. Adobe Photoshop es un editor de gráficos...
Comparte instantáneamente tus fotos y diseños

Comparte instantáneamente tus fotos y diseños

Muestre rápidamente su trabajo a clientes y compañeros de trabajo, o comparta una idea al instante por correo electrónico, texto, redes sociales y más, todo dentro de Adobe Photoshop CC. Nota: Necesitará la última versión de Photoshop CC para usar esta función. Comparte tu trabajo ahoraHaz clic en...