std::experimental:: scope_fail
|
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:
|
||
|
-
|
||
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) |
|
|
(C++11)
|
eliminador predeterminado para
unique_ptr
(plantilla de clase) |