Namespaces
Variants

std::experimental:: scope_fail

From cppreference.net

Definiert in Header <experimental/scope>
template < class EF >
class scope_fail ;
(Library Fundamentals TS v3)

Die Klassenvorlage scope_fail ist eine allgemeine Bereichs-Sicherung, die dazu dient, ihre Exit-Funktion aufzurufen, wenn ein Bereich über eine Exception verlassen wird.

scope_fail ist nicht CopyConstructible , CopyAssignable oder MoveAssignable , kann jedoch MoveConstructible sein, falls EF bestimmte Anforderungen erfüllt, was das Einkapseln eines scope_fail in ein anderes Objekt ermöglicht.

Ein scope_fail 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_fail ist aktiv, nachdem es aus einer Exit-Funktion konstruiert wurde.

Ein scope_fail kann inaktiv werden, indem release() entweder manuell oder automatisch (durch den Move-Konstruktor) aufgerufen wird. Ein inaktiver scope_fail kann auch durch Initialisierung mit einem anderen inaktiven scope_fail erhalten werden. Sobald ein scope_fail inaktiv ist, kann er nicht wieder aktiv werden.

Ein scope_fail 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:
-
Der Aufruf eines Lvalues von std:: remove_reference_t < EF > ohne Argument muss wohlgeformt sein.

Memberfunktionen

konstruiert ein neues scope_fail
(öffentliche Elementfunktion)
ruft die Exit-Funktion auf, wenn der Gültigkeitsbereich über eine Exception verlassen wird, falls das scope_fail aktiv ist, und zerstört dann das scope_fail
(öffentliche Elementfunktion)
operator=
[deleted]
scope_fail ist nicht zuweisbar
(öffentliche Elementfunktion)
Modifikatoren
macht das scope_fail inaktiv
(öffentliche Elementfunktion)

Deduktionshilfen

Hinweise

Das Erstellen eines scope_fail mit dynamischer Speicherdauer kann zu unerwartetem Verhalten führen.

Die Konstruktion eines scope_fail aus einem anderen scope_fail , der in einem anderen Thread erstellt wurde, könnte ebenfalls zu unerwartetem Verhalten führen, da die Anzahl der nicht abgefangenen Exceptions, die in verschiedenen Threads ermittelt wurde, während der Zerstörung verglichen werden könnte.

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 fehlerfreier Ausführung 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 erfolgreichen Verlassen des Gültigkeitsbereichs auf
(Klassentemplate)
Standard-Löscher für unique_ptr
(Klassentemplate)