Namespaces
Variants

std::experimental:: scope_exit

From cppreference.net

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:
-
Der Aufruf eines Lvalues von std:: remove_reference_t < EF > ohne Argument muss wohlgeformt 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)
Standard-Löscher für unique_ptr
(Klassentemplate)