std::experimental:: scope_exit
|
Definiert im Header
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_exit ; |
(Library Fundamentals TS v3) | |
Die Klassenvorlage
scope_exit
ist eine allgemeine Bereichs-Sicherung, die dazu dient, ihre Exit-Funktion aufzurufen, wenn ein Bereich verlassen wird.
scope_exit
ist nicht
CopyConstructible
,
CopyAssignable
oder
MoveAssignable
, kann jedoch
MoveConstructible
sein, falls
EF
bestimmte Anforderungen erfüllt, was das Einkapseln eines
scope_exit
in ein anderes Objekt ermöglicht.
Ein
scope_exit
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_exit
ist nach der Konstruktion aus einer Exit-Funktion aktiv.
Ein
scope_exit
kann inaktiv werden, indem
release()
aufgerufen wird, entweder manuell oder automatisch (durch den Move-Konstruktor). Ein inaktiver
scope_exit
kann auch durch Initialisierung mit einem anderen inaktiven
scope_exit
erhalten werden. Sobald ein
scope_exit
inaktiv ist, kann er nicht wieder aktiv werden.
Ein
scope_exit
enthält effektiv einen
EF
und ein
bool
-Flag, das angibt, ob es aktiv ist.
Inhaltsverzeichnis |
Template-Parameter
| EF | - | Typ der gespeicherten Exit-Funktion |
| Typanforderungen | ||
-
EF
muss entweder sein:
|
||
|
-
|
||
Memberfunktionen
konstruiert ein neues
scope_exit
(öffentliche Elementfunktion) |
|
ruft die Exit-Funktion auf, wenn der Gültigkeitsbereich verlassen wird, falls das
scope_exit
aktiv ist, und zerstört dann das
scope_exit
(öffentliche Elementfunktion) |
|
|
operator=
[deleted]
|
scope_exit
ist nicht zuweisbar
(öffentliche Elementfunktion) |
Modifikatoren |
|
macht das
scope_exit
inaktiv
(öffentliche Elementfunktion) |
|
Ableitungsleitfäden
Hinweise
Das Erstellen eines
scope_exit
mit dynamischer Speicherdauer kann zu unerwartetem Verhalten führen.
Wenn die in einem
scope_exit
-Objekt gespeicherte
EF
auf eine lokale Variable der Funktion verweist, in der sie definiert ist, z.B. als Lambda, das die Variable per Referenz erfasst, 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_exit
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 ausgeführt, wenn eine Exception auftritt 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 ausgeführt, wenn keine Exception auftritt 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 durch eine Exception auf
(Klassentemplate) |
|
|
umschließt ein Funktionsobjekt und ruft es beim normalen Verlassen des Gültigkeitsbereichs auf
(Klassentemplate) |
|
|
(C++11)
|
Standard-Löscher für
unique_ptr
(Klassentemplate) |