std::experimental:: scope_success
|
Definiert in Header
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_success ; |
(Library Fundamentals TS v3) | |
Die Klassenvorlage
scope_success
ist eine allgemeine Bereichs-Sicherung, die dazu dient, ihre Exit-Funktion aufzurufen, wenn ein Bereich normal verlassen wird.
scope_success
ist nicht
CopyConstructible
,
CopyAssignable
oder
MoveAssignable
, kann jedoch
MoveConstructible
sein, falls
EF
bestimmte Anforderungen erfüllt, was das Einkapseln eines
scope_success
in ein anderes Objekt ermöglicht.
Ein
scope_success
kann entweder aktiv sein, d.h. ruft seine Exit-Funktion bei der Zerstörung auf, oder inaktiv, d.h. tut bei der Zerstörung nichts. Ein
scope_success
ist aktiv, nachdem es aus einer Exit-Funktion konstruiert wurde.
Ein
scope_success
kann inaktiv werden, indem
release()
aufgerufen wird, entweder manuell oder automatisch (durch den Move-Konstruktor). Ein inaktiver
scope_success
kann auch durch Initialisierung mit einem anderen inaktiven
scope_success
erhalten werden. Sobald ein
scope_success
inaktiv ist, kann er nicht wieder aktiv werden.
Ein
scope_success
enthält effektiv einen
EF
und ein
bool
Flag, das angibt, ob es aktiv ist, zusammen mit einem Zähler für nicht abgefangene Ausnahmen, der zur Erkennung verwendet wird, ob der Destruktor während des Stack-Unwinding aufgerufen wird.
Inhaltsverzeichnis |
Template-Parameter
| EF | - | Typ der gespeicherten Exit-Funktion |
| Typanforderungen | ||
-
EF
muss entweder sein:
|
||
|
-
|
||
Memberfunktionen
konstruiert ein neues
scope_success
(öffentliche Elementfunktion) |
|
ruft die Exit-Funktion auf, wenn der Gültigkeitsbereich normal verlassen wird, falls das
scope_success
aktiv ist, und zerstört dann das
scope_success
(öffentliche Elementfunktion) |
|
|
operator=
[gelöscht]
|
scope_success
ist nicht zuweisbar
(öffentliche Elementfunktion) |
Modifikatoren |
|
macht das
scope_success
inaktiv
(öffentliche Elementfunktion) |
|
Deduction-Guides
Hinweise
Das Konstruieren eines
scope_success
mit dynamischer Speicherdauer kann zu unerwartetem Verhalten führen.
Das Konstruieren eines
scope_success
aus einem anderen
scope_success
, das in einem anderen Thread erstellt wurde, könnte ebenfalls zu unerwartetem Verhalten führen, da die Anzahl der nicht abgefangenen Ausnahmen, die in verschiedenen Threads ermittelt wurde, während der Zerstörung verglichen werden könnte.
Wenn die in einem
scope_success
-Objekt gespeicherte
EF
auf eine lokale Variable der Funktion verweist, in der sie definiert ist, z.B. als Lambda, das die Variable per Referenz captured, und diese Variable als Rückgabeoperand in dieser Funktion verwendet wird, könnte diese Variable bereits zurückgegeben worden sein, wenn der Destruktor des
scope_success
ausgeführt wird und die Exit-Funktion aufruft. Dies kann zu überraschendem Verhalten führen.
Beispiel
#include <iostream> #include <cstdlib> #include <string_view> #include <experimental/scope> void print_exit_status(std::string_view name, bool exit_status, bool did_throw) { std::cout << name << ":\n"; std::cout << " Throwed exception " << (did_throw ? "yes" : "no") << "\n"; std::cout << " Exit status " << (exit_status ? "finished" : "pending") << "\n\n"; } // Zufällig eine Exception werfen (50% Wahrscheinlichkeit) void maybe_throw() { if (std::rand() >= RAND_MAX / 2) throw std::exception{}; } int main() { bool exit_status{false}, did_throw{false}; // Manuelle Behandlung am "Ende des Gültigkeitsbereichs" try { maybe_throw(); exit_status = true; } catch (...) { did_throw = true; } print_exit_status("Manuelle Behandlung", exit_status, did_throw); // Verwendung von scope_exit: wird bei Verlassen des Gültigkeitsbereichs ausgeführt (Erfolg oder Exception) exit_status = did_throw = false; try { auto guard = std::experimental::scope_exit{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_exit", exit_status, did_throw); // Verwendung von scope_fail: wird nur bei Auftreten einer Exception ausgeführt exit_status = did_throw = false; try { auto guard = std::experimental::scope_fail{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_fail", exit_status, did_throw); // Verwendung von scope_success: wird nur bei erfolgreicher Ausführung ohne Exception ausgeführt exit_status = did_throw = false; try { auto guard = std::experimental::scope_success{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_success", exit_status, did_throw); }
Ausgabe:
Manuelle Behandlung: Throwed exception yes Exit status pending scope_exit: Throwed exception no Exit status finished scope_fail: Throwed exception yes Exit status finished scope_success: Throwed exception yes Exit status pending
Siehe auch
|
umschließt ein Funktionsobjekt und ruft es beim Verlassen des Gültigkeitsbereichs auf
(Klassentemplate) |
|
|
umschließt ein Funktionsobjekt und ruft es beim Verlassen des Gültigkeitsbereichs durch eine Exception auf
(Klassentemplate) |
|
|
(C++11)
|
Standard-Löscher für
unique_ptr
(Klassentemplate) |