![]() |
INTRODUCCIÓN |
La Standard Template Library (STL) es una colección
de estructuras de datos genéricas y algoritmos escritos en C++. STL no es la
primera de tales librerías, así la mayor parte de los compiladores de C++
disponen (o disponían) de librerías similares y, también, están disponibles
varias librerías comerciales. Uno de los problemas de estas librerías es que
son mutuamente incompatibles, lo que obliga a los programadores a aprender
nuevas librerías y a migrar de un proyecto a otro y de uno a otro compilador.
Sin embargo, STL ha sido adoptado por el comité ANSI de estandarización del
C++, lo que significa que está (o estará) soportado como una extensión más del
lenguaje por todos los compiladores.
El diseño de la Standard
Template Library es el resultado de varios años de investigación dirigidos por
Alexander Stepanov y Meng Lee de Hewlett-Packard, y David Musser del Rensselaer
Polytechnic Institute. Su desarrollo se inspiró en otras librerías orientadas a
objetos y en la experiencia de sus creadores en lenguajes de programación
imperativos y funcionales, tales como Ada y Scheme.
La adopción de STL ofrece varias ventajas:
·
Al ser estándar, está (o estará) disponible por todos los compiladores
y plataformas. Esto permitirá utilizar la misma librería en todos los proyectos
y disminuirá el tiempo de aprendizaje necesario para que los programadores
cambien de proyecto.
·
El uso de una librería de componentes reutilizables incrementa la
productividad ya que los programadores no tienen que escribir sus propios
algoritmos. Además, utilizar una librería libre de errores no sólo reduce el
tiempo de desarrollo, sino que también incrementa la robustez de la aplicación
en la que se utiliza.
·
Las aplicaciones pueden escribirse rápidamente ya que se construyen a
partir de algoritmos eficientes y los programadores pueden seleccionar el
algoritmo más rápido para una situación dada.
·
Se incrementa la legibilidad del código, lo que hará que éste sea mucho
más fácil de mantener.
·
Proporciona su propia gestión de memoria. El almacenamiento de memoria
es automático y portátil, así el programador ignorará problemas tales como las
limitaciones del modelo de memoria del PC.
1. TEMPLATES
Casi todas las partes de la librería están escritas
como templates. Sin el soporte
template, no se puede usar la librería estándar.
Los templates son funciones o clases
que están escritos para tipos que no han sido especificados aún. Cuando se usa
un template, se le pasan los tipos como argumentos, explícita o implícitamente.
Lo
siguiente es un ejemplo típico: una función que devuelve el máximo de dos
valores:
template <class T> inline const T& max (const
T& a, const T& b) { // if
a < b then use b else use a return a < b ?
b : a; } |
Aquí, la primera línea define T como
un tipo de dato arbitrario que es especificado por el constructor cuando éste
llama la función. Se puede usar cualquier identificador como nombre de
parámetro, pero se suele usar T. El tipo es especificado como class, aunque no tiene que ser una
clase.
Otra
función de la biblioteca estándar se usa para intercambiar los valores de dos
variables diferentes al mismo tiempo. Su definición es:
template <class T> void
swap (T& a, T& b) { //Intercambia
los valores de a y b T temp = a; a = b; b = a; } |
Siguiendo
el mismo principio, se pueden “parametrizar” clases sobre tipos arbitrarios. Esto
es útil para las clases contenedoras. Se pueden implementar las operaciones de
un contenedor para un tipo de elemento arbitrario. Por ejemplo, las clases string están parametrizadas sobre el
tipo de los caracteres y las propiedades del conjunto de caracteres.
Un template
no es compilado una vez para generar código ejecutable para un tipo, si no que
es compilado para cada combinación de tipos para los que es usado. Esto lleva a
un importante problema de los templates en la práctica: hay que tener
disponible la implementación de una función template cuando se le llama, para
poder compilar la función de tu tipo específico.
2. EL
ESPACIO DE NOMBRES STD
Al usar diferentes módulos y/o
librerías, siempre se tiene el potencial de la coincidencia de nombres. Esto se
debe a que los módulos y librerías pueden usar el mismo identificador para
diferentes cosas. Éste problema fue resuelto por la introducción del espacio de nombres (namespace) en C++. Un namespace es un ámbito seguro para
identificadores. Con diferencia a las clases, está abierto a las extensiones
que pueden ocurrir e cualquier fuente. Así, se puede usar un namespace para
definir componentes que son distribuidos para varios módulos físicos. Un
ejemplo típico de tales componentes es la librería estándar de C++, por lo que
usa un namespace.
De acuerdo con el concepto de
namespaces, existen tres opciones cuando se usa un identificador de la librería
estándar de C++:
1.
Se puede habilitar el identificador directamente. Por
ejemplo, se puede escribir std::ostream en vez
de ostream. Una sentencia completa podría ser como:
std::cout <<
std::hex << 3.4 << std::endl;
2.
Se puede usar una declaración
de uso. Por ejemplo, el siguiente fragmento de código introduce una
habilidad local para saltarse el std:: para cout y endl.
using std::cout;
using std:endl;
Así, el ejemplo en la opción 1 puede ser escrito como:
cout << std::hex << 3.4 << endl;
3.
Se puede utilizar la directiva de uso. Es la opción más fácil. De esta forma, todos los
identificadores del espacio de nombres std están disponibles como si hubiesen sido declarados
globalmente. Así, la sentencia
using
namespace std;
permite
escribir
cout << hex << 3.4 << endl;
No se debería usar esta opción cuando el contexto no esté claro.