C++
VeröffentlichtRevision 1

Fehlende Werte und Alternativen: optional und variant

std::optional<T> aus <optional> enthält entweder einen Wert vom Typ T oder keinen Wert. Das ist hilfreich, wenn eine Funktion regulär scheitern kann, etwa bei einer Suche. Ein spezieller Zahlenwert wie -1 ist dagegen ungeeignet, wenn -1 auch ein gültiges Ergebnis sein könnte.

Fehlende Werte und Alternativen: optional und variant#

Modernes C++ · Lektion 46 von 60

Voraussetzungen: Templates, Zeiger. Lernziel: Du unterscheidest „kein Ergebnis“ von einem normalen Zahlenwert.

std::optional<T> aus <optional> enthält entweder einen Wert vom Typ T oder keinen Wert. Das ist hilfreich, wenn eine Funktion regulär scheitern kann, etwa bei einer Suche. Ein spezieller Zahlenwert wie -1 ist dagegen ungeeignet, wenn -1 auch ein gültiges Ergebnis sein könnte.

C++
1#include <iostream>2#include <optional>3 4std::optional<double> teilen(double links, double rechts) {5    if (rechts == 0.0) {6        return std::nullopt;7    }8    return links / rechts;9}10 11int main() {12    const auto ergebnis = teilen(8.0, 2.0);13    if (ergebnis) {14        std::cout << *ergebnis << '\n';15    } else {16        std::cout << "Keine Division moeglich\n";17    }18}

std::nullopt bedeutet „kein enthaltener Wert“. Die Bedingung prüft die Anwesenheit, nicht ob der enthaltene Zahlenwert ungleich null ist. *ergebnis greift nach erfolgreicher Prüfung auf den Inhalt zu. Die Beispielroutine prüft nur den Nullteiler; zusätzliche Regeln für nicht endliche Werte oder Ergebnisüberlauf müssten je nach Fachproblem ergänzt werden.

Zugriff bewusst wählen#

has_value() prüft ausdrücklich auf Inhalt. value() liefert ihn oder wirft eine Ausnahme, wenn nichts enthalten ist. value_or(ersatz) liefert einen Ersatzwert bei leerem Optional. Ein Ersatz darf einen wichtigen Fehler nicht unbemerkt verschleiern.

Mehrere mögliche Typen#

std::variant<int, std::string> aus <variant> ist eine typsichere Alternative: Das Objekt enthält normalerweise genau eine der beschriebenen Typvarianten. „Typsicher“ bedeutet hier, dass die Variante den aktiven Typ mitverfolgt, statt Speicher blind umzudeuten.

Mit std::get_if<int>(&wert) erhältst du einen Zeiger auf einen enthaltenen int oder nullptr, wenn ein anderer Typ aktiv ist. std::visit wendet ein passendes Funktionsobjekt auf den aktiven Inhalt an. Durch bestimmte fehlgeschlagene Typwechsel kann eine Variant in einen besonderen wertlosen Ausnahmezustand gelangen; behandle bei anspruchsvollen Schnittstellen auch diese Möglichkeit.

Warum kein void*?#

Ein untypisierter Rohzeiger auf beliebige Daten trägt weder die Auswahl noch deren Besitzregeln mit. Optional und Variant machen normale Zustände direkt im Typ sichtbar. Sie ersetzen keine eigene Prüfung externer Daten, verhindern aber viele mehrdeutige Schnittstellen.

Übung#

Ist std::optional<int>{0} leer?

Lösung

Nein. Es enthält den gültigen Wert 0. Ein leerer Zustand entsteht etwa durch std::nullopt oder die entsprechende leere Standardkonstruktion.

Weiterlernen#

Zurück: Verschieben, std::move und Wertkategorien · Kursübersicht · Weiter: Ranges und Views ab C++20

Mitwirkende 1

Menschen, deren Änderungen in dieser Seite veröffentlicht wurden.

Kommentare 0

Kommentare sind für diese Seite deaktiviert.