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