Namespaces
Variants

std::experimental:: scope_fail

From cppreference.net

Определено в заголовочном файле <experimental/scope>
template < class EF >
class scope_fail ;
(Technical Specification v3 библиотеки fundamentals)

Класс-шаблон scope_fail является универсальной защитой области видимости, предназначенной для выхода своей функции выхода при покидании области видимости через исключение.

scope_fail не является CopyConstructible , CopyAssignable или MoveAssignable , однако может быть MoveConstructible если EF удовлетворяет определённым требованиям, что позволяет оборачивать scope_fail в другой объект.

Объект scope_fail может быть либо активным, т.е. вызывает свою завершающую функцию при уничтожении, либо неактивным, т.е. ничего не делает при уничтожении. Объект scope_fail активен после создания из завершающей функции.

Объект scope_fail может стать неактивным при вызове release() на нем, либо вручную, либо автоматически (через конструктор перемещения). Неактивный scope_fail также может быть получен при инициализации другим неактивным scope_fail . Как только scope_fail становится неактивным, он не может снова стать активным.

Объект scope_fail фактически содержит EF и флаг bool , указывающий, активен ли он, вместе со счётчиком неперехваченных исключений, используемым для определения, вызывается ли деструктор во время раскрутки стека.

Содержание

Параметры шаблона

EF - тип хранимой функции выхода
Требования к типу
-
EF должен быть либо:
-
Вызов lvalue типа std:: remove_reference_t < EF > без аргументов должен быть корректным.

Функции-члены

создает новый scope_fail
(public member function)
вызывает функцию выхода при покидании области видимости через исключение, если scope_fail активен, затем уничтожает scope_fail
(public member function)
operator=
[deleted]
scope_fail не может быть присвоен
(public member function)
Модификаторы
делает scope_fail неактивным
(public member function)

Руководства по выводу

Примечания

Создание объекта scope_fail с динамической продолжительностью хранения может привести к непредсказуемому поведению.

Создание объекта scope_fail из другого объекта scope_fail , созданного в другом потоке, также может привести к непредсказуемому поведению, поскольку счетчик неперехваченных исключений, полученный в разных потоках, может сравниваться во время уничтожения.

Пример

#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";
}
// Случайное выбрасывание исключения (50% вероятность)
void maybe_throw() {
    if (std::rand() >= RAND_MAX / 2)
        throw std::exception{};
}
int main() {
  bool exit_status{false}, did_throw{false};
  // Ручная обработка при "выходе из области видимости"
  try {
    maybe_throw();
    exit_status = true; 
  } catch (...) { did_throw = true; }
  print_exit_status("Manual handling", exit_status, did_throw);
  // Использование scope_exit: выполняется при выходе из области видимости (успех или исключение)
  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);
  // Использование scope_fail: выполняется только при возникновении исключения
  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);
  // Использование scope_success: выполняется только при отсутствии исключений
  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);
}

Вывод:

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

Смотрите также

оборачивает функциональный объект и вызывает его при выходе из области видимости
(шаблон класса)
оборачивает функциональный объект и вызывает его при нормальном выходе из области видимости
(шаблон класса)
стандартный удалитель для unique_ptr
(шаблон класса)