std::experimental:: scope_success
|
Definido en el encabezado
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_success ; |
(library fundamentals TS v3) | |
La plantilla de clase
scope_success
es un guardián de ámbito de propósito general diseñado para llamar a su función de salida cuando un ámbito se abandona normalmente.
scope_success
no es
CopyConstructible
,
CopyAssignable
ni
MoveAssignable
, sin embargo, puede ser
MoveConstructible
si
EF
cumple ciertos requisitos, lo que permite envolver un
scope_success
en otro objeto.
Un
scope_success
puede estar activo, es decir, llama a su función de salida al destruirse, o inactivo, es decir, no hace nada al destruirse. Un
scope_success
está activo después de ser construido a partir de una función de salida.
Un
scope_success
puede volverse inactivo llamando a
release()
manualmente o automáticamente (por el constructor de movimiento). También se puede obtener un
scope_success
inactivo inicializándolo con otro
scope_success
inactivo. Una vez que un
scope_success
está inactivo, no puede volver a activarse.
Un
scope_success
efectivamente contiene un
EF
y un indicador
bool
que señala si está activo, junto con un contador de excepciones no capturadas utilizado para detectar si el destructor se llama durante el desenrollado de la 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_success
(función miembro pública) |
|
llama a la función de salida cuando el ámbito se abandona normalmente si el
scope_success
está activo, luego destruye el
scope_success
(función miembro pública) |
|
|
operator=
[deleted]
|
scope_success
no es asignable
(función miembro pública) |
Modificadores |
|
hace que el
scope_success
se inactive
(función miembro pública) |
|
Guías de deducción
Notas
Construir un
scope_success
de duración de almacenamiento dinámico podría conducir a un comportamiento inesperado.
Construir un
scope_success
a partir de otro
scope_success
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.
Si el
EF
almacenado en un objeto
scope_success
se refiere a una variable local de la función donde está definido, por ejemplo, como una lambda que captura la variable por referencia, y esa variable se utiliza como operando de retorno en esa función, esa variable podría ya haber sido devuelta cuando se ejecuta el destructor del
scope_success
, llamando a la función de salida. Esto puede conducir a un comportamiento sorprendente.
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("Manejo manual", 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:
Manejo manual: 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 mediante una excepción
(plantilla de clase) |
|
|
(C++11)
|
eliminador predeterminado para
unique_ptr
(plantilla de clase) |