8Erklären Sie die Stufen der Exception Safety und wie noexcept Move-Operationen, Container und Codegenerierung beeinflusst.
Exception-Safety-Stufen beschreiben, was gilt, wenn eine Operation wirft. Die basic guarantee bedeutet, dass Invarianten erhalten bleiben und Ressourcen nicht leaken, der Zustand sich aber geändert haben kann. Die strong guarantee bedeutet Commit-oder-Rollback-Semantik: bei Fehlschlag ist der beobachtbare Zustand unverändert. Die nothrow guarantee bedeutet, dass die Operation nicht wirft. Übliche Techniken sind RAII, Arbeit auf Temporaries, Copy-and-Swap und die Anordnung von Mutationen so, dass der Commit erst nach erfolgreicher werfender Arbeit erfolgt. `noexcept` ist ein Vertrag: wirft eine `noexcept`-Funktion, wird `std::terminate` aufgerufen. Es beeinflusst auch generischen Code und Container: etwa kann `std::vector` bei Reallocation Elemente verschieben, wenn der Move-Konstruktor `noexcept` ist; andernfalls wird oft kopiert, häufig über `std::move_if_noexcept`, um Exception-Garantien zu erhalten. `noexcept` kann auch Codegenerierung oder Optimierung erleichtern, indem benötigte Exception-Propagationspfade reduziert werden – aber nur, wenn das Versprechen korrekt ist.
std::vector<T> v;
// During reallocation, an implementation may effectively do:
T* dest = allocate(new_cap);
for (T& x : old_storage) {
construct(dest++, std::move_if_noexcept(x));
}
Diese Frage mit einem KI-Coach beantworten
9Erklären Sie std::expected oder gleichwertige Outcome-Typen als Alternativen zu Exceptions für fallible Operationen.
`std::expected<T, E>` repräsentiert entweder einen erfolgreichen Wert `T` oder einen expliziten Fehler `E` und macht Fehlschlag zum Teil des Rückgabetyps der Funktion, statt auf Exception-Propagation zu setzen. Es eignet sich für fallible Operationen, bei denen Fehler erwartet werden und Aufrufer sie lokal behandeln sollen, etwa Parsing, Validierung, Netzwerkaufrufe, Storage-Lookups und retry-fähige Backend-Operationen. Der Fehlertyp sollte strukturierte Informationen tragen, etwa Fehlercode, Kategorie, Retryability, Nachricht oder HTTP/RPC-Mapping. Expected-/Outcome-Typen komponieren durch Prüfen und Propagieren von Fehlern; in C++23-artigen APIs können monadishe Operationen wie `and_then`, `transform` und `or_else` Schritte verketten, ohne tief verschachtelte Bedingungen. Im Vergleich zu Exceptions machen sie Kontrollfluss und API-Verträge explizit und funktionieren gut über exception-freie oder ABI-Grenzen hinweg; Exceptions können je nach Projektpolitik weiterhin für seltene, nicht-lokale oder wirklich außergewöhnliche Fehler geeignet sein.
enum class Errc { BadRequest, NotFound, Timeout, DbUnavailable };
struct Error {
Errc code;
bool retryable;
std::string message;
};
std::expected<User, Error> load_user(UserId id);
HttpResponse handle(UserId id) {
auto user = load_user(id);
if (!user) {
switch (user.error().code) {
case Errc::BadRequest: return {400, user.error().message};
case Errc::NotFound: return {404, "not found"};
case Errc::Timeout: return {503, "try again"};
case Errc::DbUnavailable: return {503, "service unavailable"};
}
}
return {200, serialize(*user)};
}
Diese Frage mit einem KI-Coach beantworten