Namespaces
Variants

std::experimental:: scope_fail

From cppreference.net

Definido en el encabezado <experimental/scope>
template < class EF >
class scope_fail ;
(library fundamentals TS v3)

La plantilla de clase scope_fail es un guardia de ámbito de propósito general diseñado para llamar a su función de salida cuando un ámbito se abandona mediante una excepción.

scope_fail no es CopyConstructible , CopyAssignable ni MoveAssignable , sin embargo, puede ser MoveConstructible si EF cumple con ciertos requisitos, lo que permite envolver un scope_fail en otro objeto.

Un scope_fail puede estar activo, es decir, llama a su función de salida en la destrucción, o inactivo, es decir, no hace nada en la destrucción. Un scope_fail está activo después de ser construido a partir de una función de salida.

Un scope_fail puede volverse inactivo llamando a release() manualmente o automáticamente (por el constructor de movimiento). También se puede obtener un scope_fail inactivo inicializándolo con otro scope_fail inactivo. Una vez que un scope_fail está inactivo, no puede volver a activarse.

Un scope_fail efectivamente contiene un EF y una bandera bool que indica si está activo, junto con un contador de excepciones no capturadas utilizado para detectar si el destructor se llama durante el desenrollado de pila.

Contenidos

Parámetros de plantilla

EF - tipo de función de salida almacenada
Requisitos de tipo
-
EF deberá ser:
-
Invocar un lvalue de std:: remove_reference_t < EF > sin argumentos deberá estar bien formado.

Funciones miembro

construye un nuevo scope_fail
(función miembro pública)
llama a la función de salida cuando el ámbito se abandona mediante una excepción si el scope_fail está activo, luego destruye el scope_fail
(función miembro pública)
operator=
[deleted]
scope_fail no es asignable
(función miembro pública)
Modificadores
hace que el scope_fail sea inactivo
(función miembro pública)

Guías de deducción

Notas

Construir un scope_fail de duración de almacenamiento dinámico podría conducir a un comportamiento inesperado.

La construcción de un scope_fail a partir de otro scope_fail creado en un hilo diferente también podría conducir a un comportamiento inesperado, ya que el recuento de excepciones no capturadas obtenido en diferentes hilos podría compararse durante la destrucción.

Ejemplo

#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";
}
// Lanzar excepción aleatoriamente (50% de probabilidad)
void maybe_throw() {
    if (std::rand() >= RAND_MAX / 2)
        throw std::exception{};
}
int main() {
  bool exit_status{false}, did_throw{false};
  // Manejo manual al "final del ámbito"
  try {
    maybe_throw();
    exit_status = true; 
  } catch (...) { did_throw = true; }
  print_exit_status("Manual handling", exit_status, did_throw);
  // Usando scope_exit: se ejecuta al salir del ámbito (éxito o excepción)
  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);
  // Usando scope_fail: se ejecuta solo si ocurre una excepción
  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);
  // Usando scope_success: se ejecuta solo si no ocurre excepción
  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);
}

Salida:

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

Véase también

envuelve un objeto función y lo invoca al salir del ámbito
(plantilla de clase)
envuelve un objeto función y lo invoca al salir del ámbito normalmente
(plantilla de clase)
eliminador predeterminado para unique_ptr
(plantilla de clase)