Namespaces
Variants

std::experimental:: scope_success

From cppreference.net

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