std::experimental:: scope_fail
|
Определено в заголовочном файле
<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
должен быть либо:
|
||
|
-
|
||
Функции-члены
создает новый
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
Смотрите также
|
оборачивает функциональный объект и вызывает его при выходе из области видимости
(шаблон класса) |
|
|
оборачивает функциональный объект и вызывает его при нормальном выходе из области видимости
(шаблон класса) |
|
|
(C++11)
|
стандартный удалитель для
unique_ptr
(шаблон класса) |