Namespaces
Variants

std::experimental:: scope_exit

From cppreference.net

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:
-
Invocar un lvalue de std:: remove_reference_t < EF > sin argumentos deberá estar bien formado.

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)
eliminador predeterminado para unique_ptr
(plantilla de clase)