std::experimental:: scope_exit
|
Definido en el encabezado
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_exit ; |
(library fundamentals TS v3) | |
La plantilla de clase
scope_exit
es un guardia de ámbito de propósito general diseñado para llamar a su función de salida cuando se abandona un ámbito.
scope_exit
no es
CopyConstructible
,
CopyAssignable
ni
MoveAssignable
, sin embargo, puede ser
MoveConstructible
si
EF
cumple ciertos requisitos, lo que permite envolver un
scope_exit
en otro objeto.
Un
scope_exit
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_exit
está activo después de ser construido a partir de una función de salida.
Un
scope_exit
puede volverse inactivo llamando a
release()
manualmente o automáticamente (por el constructor de movimiento). También se puede obtener un
scope_exit
inactivo inicializándolo con otro
scope_exit
inactivo. Una vez que un
scope_exit
está inactivo, no puede volver a activarse.
Un
scope_exit
efectivamente contiene un
EF
y un indicador
bool
que señala si está activo.
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_exit
(función miembro pública) |
|
llama a la función de salida cuando se abandona el ámbito si el
scope_exit
está activo, luego destruye el
scope_exit
(función miembro pública) |
|
|
operator=
[deleted]
|
scope_exit
no es asignable
(función miembro pública) |
Modificadores |
|
hace que el
scope_exit
sea inactivo
(función miembro pública) |
|
Guías de deducción
Notas
Construir un
scope_exit
de duración de almacenamiento dinámico podría conducir a un comportamiento inesperado.
Si el
EF
almacenado en un objeto
scope_exit
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, es posible que esa variable ya haya sido devuelta cuando se ejecuta el destructor del
scope_exit
, 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"; } // 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); }
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 mediante una excepción
(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) |