Namespaces
Variants

std::experimental:: scope_exit

From cppreference.net

Défini dans l'en-tête <experimental/scope>
template < class EF >
class scope_exit ;
(library fundamentals TS v3)

Le modèle de classe scope_exit est un garde de portée à usage général destiné à appeler sa fonction de sortie lorsqu'une portée est quittée.

scope_exit n'est pas CopyConstructible , CopyAssignable ni MoveAssignable , cependant, il peut être MoveConstructible si EF satisfait certaines exigences, ce qui permet d'encapsuler un scope_exit dans un autre objet.

Un scope_exit peut être soit actif, c'est-à-dire qu'il appelle sa fonction de sortie lors de la destruction, soit inactif, c'est-à-dire qu'il ne fait rien lors de la destruction. Un scope_exit est actif après avoir été construit à partir d'une fonction de sortie.

Un scope_exit peut devenir inactif en appelant release() sur celui-ci manuellement ou automatiquement (par le constructeur de déplacement). Un scope_exit inactif peut également être obtenu en l'initialisant avec un autre scope_exit inactif. Une fois qu'un scope_exit est inactif, il ne peut plus redevenir actif.

Un scope_exit contient effectivement un EF et un indicateur bool indiquant s'il est actif.

Table des matières

Paramètres du modèle

EF - type de fonction de sortie stockée
Exigences de type
-
EF doit être soit :
-
L'appel d'une lvalue de std:: remove_reference_t < EF > sans argument doit être bien formé.

Fonctions membres

construit un nouveau scope_exit
(fonction membre publique)
appelle la fonction de sortie lorsque la portée est quittée si le scope_exit est actif, puis détruit le scope_exit
(fonction membre publique)
operator=
[deleted]
scope_exit n'est pas assignable
(fonction membre publique)
Modificateurs
rend le scope_exit inactif
(fonction membre publique)

Guides de déduction

Notes

La construction d'un scope_exit de durée de stockage dynamique peut entraîner un comportement inattendu.

Si le EF stocké dans un objet scope_exit fait référence à une variable locale de la fonction où il est défini, par exemple comme une lambda capturant la variable par référence, et que cette variable est utilisée comme opérande de retour dans cette fonction, cette variable pourrait déjà avoir été retournée lorsque le destructeur du scope_exit s'exécute, appelant la fonction de sortie. Cela peut conduire à un comportement surprenant.

Exemple

#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";
}
// Lance aléatoirement une exception (50% de chance)
void maybe_throw() {
    if (std::rand() >= RAND_MAX / 2)
        throw std::exception{};
}
int main() {
  bool exit_status{false}, did_throw{false};
  // Gestion manuelle à la "fin de portée"
  try {
    maybe_throw();
    exit_status = true; 
  } catch (...) { did_throw = true; }
  print_exit_status("Gestion manuelle", exit_status, did_throw);
  // Utilisation de scope_exit : s'exécute à la sortie de portée (succès ou 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);
  // Utilisation de scope_fail : s'exécute uniquement si une exception se produit
  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);
  // Utilisation de scope_success : s'exécute uniquement si aucune exception ne se produit
  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);
}

Sortie :

Gestion manuelle :
  Exception lancée    oui
  Statut de sortie    en attente
scope_exit :
  Exception lancée    non
  Statut de sortie    terminé
scope_fail :
  Exception lancée    oui
  Statut de sortie    terminé
scope_success :
  Exception lancée    oui
  Statut de sortie    en attente

Voir aussi

encapsule un objet fonction et l'invoque lors de la sortie de portée via une exception
(modèle de classe)
encapsule un objet fonction et l'invoque lors de la sortie normale de portée
(modèle de classe)
suppresseur par défaut pour unique_ptr
(modèle de classe)