Chargement...

Aperçu de la bibliothèque standard C++

Découvrez la bibliothèque standard C++, les conteneurs STL, les algorithmes et les composants essentiels du développement moderne.

La bibliothèque standard C++ (y compris la STL) fournit des composants efficaces, sûrs et prêts à l’emploi, augmentant considérablement la productivité : conteneurs, itérateurs, algorithmes, chaînes de caractères, flux d’E/S, utilitaires temporels, système de fichiers, concurrence et types utilitaires. Cet article présente les parties les plus utilisées à travers des explications courtes et des exemples fonctionnels.


1) Structure des en-têtes et inclusion de base

La bibliothèque standard est modulaire. Inclure uniquement les en-têtes nécessaires est important pour la performance et la rapidité de compilation.

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


2) Conteneurs

Les conteneurs stockent des données, se parcourent au moyen d’itérateurs et se traitent via les algorithmes STL.

TypeExemplesUtilisation
Séquentielsvector, array, deque, listvector est le choix général ; array pour une taille fixe.
Associatifs ordonnésmap, set, multimapArbres triés ; recherche en O(log n)
Associatifs non ordonnésunordered_map, unordered_setBasés sur des tables de hachage ; accès moyen O(1)
Piles et filesqueue, priority_queue, stackTraitement FIFO/LIFO ou par priorité

#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) Itérateurs et algorithmes

Les itérateurs abstraient les conteneurs, tandis que <algorithm> fournit des opérations génériques indépendantes du conteneur.


#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 C++20 (brièvement)

Ranges permet d’enchaîner les algorithmes dans un style « pipeline ». Nécessite le support 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 et regex

std::string possède sa propre mémoire ; std::string_view est une vue non possédante (attention à la durée de vie). <regex> sert aux expressions régulières.


#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) Flux E/S (iostream, fstream, sstream)

Les flux permettent de chaîner facilement les opérations d’entrée/sortie. fstream gère les fichiers, stringstream facilite l’analyse textuelle.


#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) Gestion du temps (chrono)

<chrono> permet de mesurer des durées et manipuler des temps.


#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) Système de fichiers (filesystem)

Fournit une gestion multiplateforme des fichiers et répertoires. Les anciens GCC nécessitaient -lstdc++fs, ce n’est plus le cas avec les versions modernes.


#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) Nombres aléatoires (random)

Le générateur Mersenne Twister (mt19937) et les distributions modernes facilitent la génération de nombres aléatoires.


#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) Mémoire et types utilitaires

<memory> inclut les smart pointers (unique_ptr, shared_ptr, weak_ptr). <optional> représente un « valeur ou rien », <variant> un union typé, <any> un conteneur générique (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 << "aucun\n";

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

11) Concurrence (thread, mutex, future)

Fournit les primitives de base pour le multithreading et la synchronisation.


#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 << " resultat=" << fut.get() << "\n";
}

12) Outils numériques (numeric, cmath)

<numeric> fournit des fonctions d’accumulation et de réduction. <cmath> fournit les fonctions mathématiques classiques.


#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 << "moyenne=" << avg << "\n";
}

13) Résumé rapide (Quand utiliser quoi ?)


14) TL;DR

  • La STL repose sur le trio : conteneurs + itérateurs + algorithmes.
  • vector est le choix par défaut ; map/set pour des données triées, unordered_* pour des accès rapides.
  • algorithm/numeric offrent des transformations génériques. Avec C++20, ranges rend le code plus lisible.
  • string_view permet un accès non-copié (attention à la durée de vie des objets).
  • chrono, filesystem, random simplifient les opérations système.
  • Types modernes : optional, variant, any, smart pointers.
  • Pour le multithreading : thread/mutex/future.
  • Tous les exemples fonctionnent sous Visual Studio 2022 et GCC 11+.

Articles connexes