C++ Tutorial de STL

La Biblioteca de Plantillas Estándar de C++ (Standard Template Library, STL) es un potente conjunto de clases y funciones plantilla de C++ que proporciona una serie de algoritmos y estructuras de datos genéricos y reutilizables.

El diseño de STL se basa en la programación genérica, lo que significa que el uso de plantillas permite escribir código independiente de cualquier tipo de datos específico.

STL se divide en varios componentes, incluidos contenedores (Containers), iteradores (Iterators), algoritmos (Algorithms), objetos de función (Function Objects) y adaptadores (Adapters), entre otros.

Ventajas de usar STL:

  • Reutilización de código: STL proporciona una gran cantidad de estructuras de datos y algoritmos genéricos, lo que reduce el trabajo de escribir código repetitivo.
  • Optimización del rendimiento: Los algoritmos y estructuras de datos de STL están optimizados para ofrecer el mejor rendimiento.
  • Programación genérica: Mediante plantillas, STL admite la programación genérica, lo que permite que los algoritmos y estructuras de datos se apliquen a cualquier tipo de datos.
  • Fácil mantenimiento: El diseño de STL hace que el código sea más modular, fácil de leer y mantener.

El núcleo de la Biblioteca de Plantillas Estándar de C++ incluye los siguientes componentes importantes:

Componente Descripción
Contenedores (Containers)

Los contenedores son uno de los componentes más básicos de STL y proporcionan diversas estructuras de datos, incluidos vector (vector), list (lista enlazada), queue (cola), stack (pila), set (conjunto), map (mapa), etc. Estos contenedores tienen diferentes características y usos, por lo que se puede elegir el contenedor adecuado según las necesidades reales.

Algoritmos (Algorithms) STL proporciona una gran cantidad de algoritmos para realizar diversas operaciones sobre los elementos de los contenedores, como ordenación, búsqueda, copia, movimiento, transformación, etc. Al usar estos algoritmos no es necesario preocuparse por el tipo específico de contenedor, solo hay que especificar el rango sobre el que se operará.
Iteradores (iterators) Los iteradores se utilizan para recorrer los elementos de un contenedor, permitiendo acceder a ellos de manera uniforme sin preocuparse por los detalles internos de la implementación del contenedor. STL proporciona varios tipos de iteradores, incluidos iteradores de acceso aleatorio, iteradores bidireccionales, iteradores hacia adelante e iteradores de entrada/salida.
Objetos de función (Function Objects) Los objetos de función son objetos que se pueden invocar como funciones y se utilizan en diversas operaciones de los algoritmos. STL proporciona varios objetos de función, incluidos objetos de función unarios, objetos de función binarios, predicados, etc., para satisfacer diferentes necesidades.
Adaptadores (Adapters) Los adaptadores se utilizan para adaptar un contenedor o iterador a otro tipo de contenedor o iterador, con el fin de satisfacer necesidades específicas. STL proporciona varios adaptadores, incluidos adaptador de pila (stack adapter), adaptador de cola (queue adapter) y adaptador de cola de prioridad (priority queue adapter), entre otros.

Estos componentes cuentan con una gran cantidad de funciones predefinidas que nos ayudan a manejar tareas complejas de manera sencilla.


Contenedores

Los contenedores son secuencias utilizadas para almacenar datos; proporcionan diferentes métodos de almacenamiento y modos de acceso.

Los contenedores en STL se pueden dividir en tres categorías:

1. Contenedores secuenciales: almacenan secuencias de elementos y permiten el recorrido bidireccional.

  • std::vector: arreglo dinámico, admite acceso aleatorio rápido.
  • std::deque: cola de doble extremo, admite inserción y eliminación rápidas.
  • std::list: lista enlazada, admite inserción y eliminación rápidas, pero no admite acceso aleatorio.

2. Contenedores asociativos: almacenan pares clave-valor; cada elemento tiene una clave (key) y un valor (value), y los elementos se organizan mediante la clave.

  • std::set: conjunto, no permite elementos duplicados.
  • std::multiset: conjunto múltiple, permite que varios elementos tengan la misma clave.
  • std::map: mapa, cada clave se asigna a un valor.
  • std::multimap: mapa múltiple, almacena pares clave-valor (pair), donde la clave es única, pero el valor puede repetirse, lo que permite que una clave se asigne a varios valores.

3. Contenedores desordenados (introducidos en C++11): tablas hash, admiten búsqueda, inserción y eliminación rápidas.

  • std::unordered_set: conjunto desordenado.
  • std::unordered_multiset: conjunto múltiple desordenado.
  • std::unordered_map: mapa desordenado.
  • std::unordered_multimap: mapa múltiple desordenado.

El siguiente programa demuestra el contenedor vector (una plantilla estándar de C++), que es muy similar a un arreglo; la única diferencia es que, cuando vector necesita ampliar su tamaño, gestiona automáticamente sus propias necesidades de almacenamiento:

Ejemplos

#include <iostream> #include <vector> using namespace std; int main() { // Crear un vector para almacenar int vector<int> vec; int i; // Mostrar el tamaño original de vec cout << "vector size = " << vec.size() << endl; // Insertar 5 valores en el vector for(i = 0; i < 5; i++){ vec.push_back(i); } // Mostrar el tamaño de vec después de expandirse cout << "extended vector size = " << vec.size() << endl; // Acceder a los 5 valores del vector for(i = 0; i < 5; i++){ cout << "value of vec [" << i << "] = " << vec[i] << endl; } // Usar el iterador para acceder a los valores vector<int>::iterator v = vec.begin(); while( v != vec.end()) { cout << "value of v = " << *v << endl; v++; } return 0; }

Cuando el código anterior se compila y ejecuta, produce los siguientes resultados:

vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4

Con respecto a las diversas funciones utilizadas en el ejemplo anterior, hay varios puntos a tener en cuenta:

  • La función miembro push_back( ) inserta un valor al final del vector y, si es necesario, amplía el tamaño del vector.
  • La función size( ) muestra el tamaño del vector.
  • La función begin( ) devuelve un iterador que apunta al inicio del vector.
  • La función end( ) devuelve un iterador que apunta al final del vector.

STL es una parte indispensable de la programación en C++; amplía enormemente las funcionalidades de C++ y permite a los programadores escribir código más eficiente y legible.

Dominar el uso de STL es muy importante para cualquier programador de C++.

Otras extensiones