Cargando...

Visión general de la biblioteca estándar de C++

Aprende la biblioteca estándar de C++, incluyendo contenedores STL, algoritmos y componentes esenciales del desarrollo moderno.

La biblioteca estándar de C++ (incluyendo la STL) proporciona componentes eficientes, seguros y listos para usar, que incrementan significativamente la productividad: contendores, iteradores, algoritmos, cadenas de texto, flujos de E/S, utilidades de tiempo, sistema de archivos, concurrencia y tipos auxiliares. Este artículo resume las partes más importantes y ofrece ejemplos cortos y funcionales.


1) Estructura de encabezados e inclusión básica

La biblioteca estándar es modular. Incluir únicamente los encabezados necesarios es importante para el rendimiento y el tiempo de compilación.

Compilación: MSVC: cl /std:c++20 main.cpp GCC/Clang: g++ -std=c++20 main.cpp -o app


2) Contenedores

Los contenedores almacenan datos, se recorren mediante iteradores y se procesan con algoritmos de la STL.

TipoEjemplosUso
Secuencialesvector, array, deque, listvector es la opción general; array para tamaño fijo.
Asociativos ordenadosmap, set, multimapBasados en árboles; búsqueda O(log n).
Asociativos no ordenadosunordered_map, unordered_setTablas hash; promedio O(1).
Pilas y colasqueue, priority_queue, stackProcesamiento FIFO, LIFO o por prioridad.

#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;

int main() {
    vector<int> v; v.reserve(5);
    v.emplace_back(3); v.emplace_back(1); v.emplace_back(2);

    unordered_map<string,int> freq;
    for (int x : v) freq[to_string(x)]++;

    cout << "v size=" << v.size() << ", 2 freq=" << freq["2"] << "\n";
}

3) Iteradores y algoritmos

Los iteradores abstraen el acceso a los contenedores. El encabezado <algorithm> proporciona operaciones genéricas independientes del contenedor.


#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
using namespace std;

int main() {
    vector<int> a{5,1,4,2,3};

    sort(a.begin(), a.end());
    int s = accumulate(a.begin(), a.end(), 0);

    auto it = find(a.begin(), a.end(), 4);
    if (it != a.end()) *it = 40;

    transform(a.begin(), a.end(), a.begin(),
              [](int x){ return x + 10; });

    for (int x : a) cout << x << ' ';
}

4) Ranges en C++20 (breve)

Ranges permite encadenar algoritmos en estilo “pipeline”. Requiere soporte C++20.


#include <vector>
#include <ranges>
#include <iostream>
using namespace std;

int main() {
    vector<int> v{1,2,3,4,5,6};
    auto even_times10 = v 
      | views::filter([](int x){ return x%2==0; })
      | views::transform([](int x){ return x*10; });

    for (int x : even_times10) cout << x << ' ';
}

5) string, string_view y regex

std::string posee su propia memoria; std::string_view es una vista no propietaria (cuidado con el tiempo de vida). <regex> sirve para expresiones regulares.


#include <string>
#include <string_view>
#include <regex>
#include <iostream>
using namespace std;

bool is_email(string_view s) {
    static const regex re(R"((\w+)(\.\w+)*@(\w+)(\.\w+)+)");
    return regex_match(s.begin(), s.end(), re);
}

int main() {
    string name = "Ada Lovelace";
    string_view view = name;
    cout << view.substr(0, 3) << "\n";
    cout << boolalpha << is_email("dev@example.com") << "\n";
}

6) Flujos de entrada/salida (iostream, fstream, sstream)

Los flujos se encadenan fácilmente con operadores. fstream maneja archivos, stringstream facilita el análisis de texto.


#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
using namespace std;

int main() {
    ofstream out("data.txt");
    out << "42, Modern C++\n"; out.close();

    ifstream in("data.txt");
    string line; getline(in, line);

    stringstream ss(line);
    int id; char comma; string title;
    ss >> id >> comma; getline(ss, title);
    cout << "id=" << id << " title=" << title << "\n";
}

7) Tiempo y duración (chrono)

<chrono> permite medir intervalos de tiempo y gestionar objetos temporales.


#include <chrono>
#include <iostream>
using namespace std;

int main() {
    using namespace chrono;
    auto t0 = steady_clock::now();

    for (volatile int i=0;i<1000000;i++) {}

    auto t1 = steady_clock::now();
    cout << "ms=" << duration_cast<milliseconds>(t1 - t0).count() << "\n";
}

8) Sistema de archivos (filesystem)

Proporciona gestión multiplataforma de archivos y directorios. Las versiones antiguas de GCC requerían -lstdc++fs; las modernas ya no.


#include <filesystem>
#include <iostream>
using namespace std;
namespace fs = std::filesystem;

int main() {
    for (const auto& e : fs::directory_iterator(".")) {
        cout << e.path().filename().string() << "\n";
    }
}

9) Números aleatorios (random)

C++ moderno utiliza el generador Mersenne Twister (mt19937) y distribuciones estadísticas.


#include <random>
#include <iostream>
using namespace std;

int main() {
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<int> dist(1, 6);

    for (int i=0;i<5;i++) cout << dist(gen) << ' ';
}

10) Memoria y tipos auxiliares

<memory> incluye smart pointers (unique_ptr, shared_ptr, weak_ptr). <optional> representa “valor o ninguno”, <variant> es una unión tipada, <any> permite almacenar cualquier tipo (type-erasure).


#include <memory>
#include <optional>
#include <variant>
#include <iostream>
using namespace std;

optional<int> parse_pos_int(int x) { return x>=0 ? optional<int>(x) : nullopt; }

int main() {
    auto p = make_unique<int>(42);
    cout << *p << "\n";

    if (auto v = parse_pos_int(-7)) cout << *v; else cout << "ninguno\n";

    variant<int,string> v2 = 10; v2 = string("texto");
    visit([](auto& t){ cout << t << "\n"; }, v2);
}

11) Concurrencia (thread, mutex, future)

Proporciona mecanismos básicos de ejecución multihilo y sincronización.


#include <thread>
#include <mutex>
#include <future>
#include <iostream>
using namespace std;

mutex m; int counter = 0;

void work(int n){
    lock_guard<mutex> lk(m);
    counter += n;
}

int main() {
    thread t1(work, 1), t2(work, 2);
    t1.join(); t2.join();

    auto fut = async(launch::async, []{ return 40 + 2; });
    cout << "counter=" << counter << " resultado=" << fut.get() << "\n";
}

12) Herramientas numéricas (numeric, cmath)

<numeric> ofrece acumulación y reducción; <cmath> proporciona funciones matemáticas estándar.


#include <vector>
#include <numeric>
#include <iostream>
using namespace std;

int main() {
    vector<double> x{1.0, 2.0, 3.0};
    double avg = accumulate(x.begin(), x.end(), 0.0) / x.size();
    cout << "promedio=" << avg << "\n";
}

13) Referencia rápida (¿cuándo usar qué?)


14) TL;DR

  • STL se basa en el trío: contenedores + iteradores + algoritmos.
  • vector es la opción por defecto; map/set para datos ordenados, unordered_* para acceso rápido.
  • algorithm/numeric permiten transformaciones genéricas; ranges (C++20) mejora la expresividad.
  • string_view permite acceso sin copia (cuidado con la vida útil).
  • chrono, filesystem, random simplifican tareas del sistema.
  • Herramientas modernas: optional, variant, any, smart pointers.
  • Para concurrencia: thread/mutex/future.
  • Todos los ejemplos funcionan en Visual Studio 2022 y GCC 11+.

Artículos relacionados