Namensräume
Varianten
Aktionen

std::experimental::scope_fail

Von cppreference.com
 
 
 
 
std::experimental::scope_fail
 
Definiert in Header <experimental/scope>
template< class EF >
class scope_fail;
(library fundamentals TS v3)

Die Klassenvorlage scope_fail ist ein universeller Geltungsbereichswächter, der dazu bestimmt ist, seine Austrittsfunktion aufzurufen, wenn ein Geltungsbereich durch eine Ausnahme verlassen wird.

scope_fail ist nicht Kopierkonstruierbar, Kopierzuweisbar oder Verschiebungszuweisbar, kann aber verschiebbar konstruierbar sein, wenn EF bestimmte Anforderungen erfüllt, was das Verpacken eines scope_fail in ein anderes Objekt ermöglicht.

Ein scope_fail kann entweder aktiv sein, d.h. seine Austrittsfunktion beim Zerstören aufrufen, oder inaktiv, d.h. beim Zerstören nichts tun. Ein scope_fail ist nach der Konstruktion aus einer Austrittsfunktion aktiv.

Ein scope_fail kann durch manuelles oder automatisches (durch den Verschiebekonstruktor) Aufrufen von release() inaktiv werden. 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 hält effektiv ein EF und ein bool Flag, das angibt, ob es aktiv ist, zusammen mit einem Zähler für unbehandelte Ausnahmen, der zur Erkennung verwendet wird, ob der Destruktor während des Stack-Abwickelns aufgerufen wird.

Inhalt

[bearbeiten] Template-Parameter

EF - Typ der gespeicherten Exit-Funktion
Typanforderungen
-
EF muss entweder sein:
-
Der Aufruf eines lvalue von std::remove_reference_t<EF> ohne Argument muss wohlgeformt sein.

[bearbeiten] Member-Funktionen

konstruiert einen neuen scope_fail
(public member function) [bearbeiten]
ruft die Austrittsfunktion auf, wenn der Geltungsbereich durch eine Ausnahme verlassen wird, wenn der scope_fail aktiv ist, und zerstört dann den scope_fail
(public member function) [bearbeiten]
operator=
[gelöscht]
scope_fail ist nicht zuweisbar
(öffentliche Memberfunktion)
Modifizierer
macht den scope_fail inaktiv
(public member function) [bearbeiten]

[bearbeiten] Deduktionsleitfäden

[bearbeiten] Hinweise

Die Konstruktion eines scope_fail mit dynamischer Speicherverwaltung kann zu unerwartetem Verhalten führen.

Die Konstruktion eines scope_fail aus einem anderen scope_fail, der in einem anderen Thread erstellt wurde, kann ebenfalls zu unerwartetem Verhalten führen, da der Zähler für unbehandelte Ausnahmen, der in verschiedenen Threads ermittelt wurde, während der Zerstörung verglichen werden kann.

[bearbeiten] 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";
}
 
// Randomly throw an exception (50% chance)
void maybe_throw() {
    if (std::rand() >= RAND_MAX / 2)
        throw std::exception{};
}
 
int main() {
  bool exit_status{false}, did_throw{false};
 
  // Manual handling at "end of scope"
  try {
    maybe_throw();
    exit_status = true; 
  } catch (...) { did_throw = true; }
  print_exit_status("Manual handling", exit_status, did_throw);
 
  // Using scope_exit: runs on scope exit (success or 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);
 
  // Using scope_fail: runs only if an exception occurs
  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);
 
  // Using scope_success: runs only if no exception occurs
  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

Manual handling:
  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

[bearbeiten] Siehe auch

umschließt ein Funktions-Objekt und ruft es beim Verlassen des Geltungsbereichs auf
(Klassenvorlage) [bearbeiten]
umschließt ein Funktions-Objekt und ruft es beim normalen Verlassen des Geltungsbereichs auf
(Klassenvorlage) [bearbeiten]
Standard-Deleter für unique_ptr
(Klassen-Template) [edit]