std::experimental:: scope_exit
|
Определено в заголовке
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_exit ; |
(Technical Specification v3 библиотеки фундаментальных компонентов) | |
Класс-шаблон
scope_exit
является универсальной защитой области видимости, предназначенной для выхода своей функции выхода при выходе из области видимости.
scope_exit
не является
CopyConstructible
,
CopyAssignable
или
MoveAssignable
, однако может быть
MoveConstructible
, если
EF
удовлетворяет определённым требованиям, что позволяет оборачивать
scope_exit
в другой объект.
Объект
scope_exit
может быть активным, т.е. вызывать свою завершающую функцию при разрушении, или неактивным, т.е. не делать ничего при разрушении.
scope_exit
активен после создания из завершающей функции.
Объект
scope_exit
может стать неактивным при вызове метода
release()
либо вручную, либо автоматически (через конструктор перемещения). Неактивный
scope_exit
также может быть получен при инициализации другим неактивным объектом
scope_exit
. После того как
scope_exit
становится неактивным, он не может снова стать активным.
Объект
scope_exit
фактически содержит
EF
и флаг
bool
, указывающий, активен ли он.
Содержание |
Параметры шаблона
| EF | - | тип хранимой функции выхода |
| Требования к типу | ||
-
EF
должен быть либо:
|
||
|
-
|
||
Функции-члены
создает новый
scope_exit
(публичная функция-член) |
|
вызывает функцию выхода при выходе из области видимости, если
scope_exit
активен, затем уничтожает
scope_exit
(публичная функция-член) |
|
|
operator=
[deleted]
|
scope_exit
не может быть присвоен
(публичная функция-член) |
Модификаторы |
|
делает
scope_exit
неактивным
(публичная функция-член) |
|
Руководства по выводу
Примечания
Создание объекта
scope_exit
с динамической продолжительностью хранения может привести к непредсказуемому поведению.
Если
EF
, хранимый в объекте
scope_exit
, ссылается на локальную переменную функции, в которой он определен, например, как лямбда-выражение, захватывающее переменную по ссылке, и эта переменная используется в качестве операнда возврата в этой функции, эта переменная может быть уже возвращена, когда деструктор
scope_exit
выполняет вызов функции выхода. Это может привести к неожиданному поведению.
Пример
#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
(шаблон класса) |