Wird geladen...

Überblick über die C++-Standardbibliothek

Lernen Sie die C++-Standardbibliothek mit STL-Containern, Algorithmen und wichtigen Komponenten für moderne C++-Entwicklung.

Die C++ Standardbibliothek (einschließlich STL) bietet effiziente, sichere und gebrauchsfertige Komponenten, die die Produktivität erheblich steigern: Container, Iteratoren, Algorithmen, Zeichenketten, E/A-Streams, Zeitfunktionen, Dateisystem, Parallelität und Hilfstypen. Dieser Artikel gibt einen Überblick über die wichtigsten Teile der Bibliothek und zeigt kurze, lauffähige Beispiele.


1) Aufbau und Einbindung von Header-Dateien

Die Standardbibliothek ist modular aufgebaut. Es ist wichtig, nur die benötigten Header einzubinden, um Kompilierzeit und Speicherverbrauch zu optimieren.

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


2) Container

Container speichern Daten, werden mit Iteratoren durchlaufen und mit Algorithmen verarbeitet.

TypBeispieleVerwendung
Sequenziellvector, array, deque, listvector für allgemeinen Gebrauch; array für feste Größe.
Geordnet (Assoziativ)map, set, multimapBaumbasiert; geordneter Zugriff, O(log n) Suche.
Ungeordnet (Hash-basiert)unordered_map, unordered_setHash-Tabellen; durchschnittlich O(1) Zugriff.
Queues/Stacksqueue, priority_queue, stackFIFO-, LIFO- oder Prioritätsverarbeitung.

#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) Iteratoren und Algorithmen

Iteratoren abstrahieren den Zugriff auf Container. <algorithm> bietet generische Operationen, die unabhängig vom Containertyp funktionieren.


#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 sum = 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) C++20 Ranges (Kurzüberblick)

Ranges ermöglichen das Verketten von Algorithmen im „Pipeline“-Stil. Erfordert C++20-Unterstützung.


#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 und regex

std::string besitzt Speicher; std::string_view ist eine nicht besitzende Ansicht (Vorsicht bei der Lebensdauer). <regex> ermöglicht Musterabgleiche (Reguläre Ausdrücke).


#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) Ein-/Ausgabe-Streams (iostream, fstream, sstream)

Streams lassen sich mit Operatoren verketten. fstream liest/schreibt Dateien, stringstream dient der Textanalyse.


#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) Zeitmessung (chrono)

Mit <chrono> lassen sich Zeitspannen messen und Datums-/Zeitoperationen durchführen.


#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) Dateisystem (filesystem)

Plattformunabhängige Datei- und Ordneroperationen. In älteren GCC-Versionen war -lstdc++fs erforderlich, bei modernen Compilern nicht mehr.


#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) Zufallszahlen (random)

Moderne C++-Implementierungen verwenden den Mersenne-Twister (mt19937) und Verteilungen.


#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) Speicherverwaltung und Hilfstypen

<memory> bietet Smart Pointer (unique_ptr, shared_ptr, weak_ptr). <optional> repräsentiert „Wert oder leer“, <variant> ist ein typensicheres Union, und <any> erlaubt typunspezifische Speicherung (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 << "leer\n";

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

11) Nebenläufigkeit (thread, mutex, future)

Grundlegende Mehrfach-Threading-Klassen und Synchronisationsmechanismen.


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

12) Numerische Werkzeuge (numeric, cmath)

<numeric> bietet Summierung und Aggregation, <cmath> stellt mathematische Funktionen bereit.


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

13) Schnellreferenz (Wann was verwenden?)


14) TL;DR

  • STL basiert auf dem Trio: Container + Iteratoren + Algorithmen.
  • vector ist die Standardwahl; map/set für geordnete Daten, unordered_* für schnelle Zugriffe.
  • algorithm/numeric bieten generische Datenverarbeitung; C++20 ranges erhöhen Lesbarkeit.
  • string_view bietet zero-copy Zugriff (Lebensdauer beachten).
  • chrono, filesystem, random erleichtern Systemaufgaben.
  • Moderne Helfer: optional, variant, any, smart pointers.
  • Für Nebenläufigkeit: thread/mutex/future; in Performance-kritischen Bereichen mit Bedacht einsetzen.
  • Alle Beispiele sind mit Visual Studio 2022 und GCC 11+ kompatibel.

Ähnliche Artikel