标准库中是否有一个类/模板可以在作用域外执行任务?

3

我们有一些需要手动释放的资源。除了显式地编写 RAII 包装器来管理其资源之外,是否存在 std 库中自动执行 lambda 任务的内置模板或类?

{
    auto resource = InitResource();        
    GuardedTask task ([&resource]{ FreeUp(resource); }); // Simply bind a clean up lambda
    ...
    if(failed_condition_met) { return false; } // Free up
    ...
    if(another_failed_condition_met) { return false; } // Free up

} // Free up

该类可能会有以下行为,但我想知道轮子是否已经在std库中构建,或者我应该编写自己的轮子。
struct GuardedTask
{
    std::function<void()> task;
    GuardedTask(std::function<void()> f): task(f) {}
    ~GuardedTask(){ task(); }
};

2
请注意,您必须删除复制构造函数/赋值运算符。 - Jarod42
2个回答

3

这个模式被称为作用域后备,不仅可以用于 RAII 清理,还可用于事务安全函数等许多其他用途。不幸的是,目前没有标准化的作用域后备,但有建议 P0052 旨在实现此功能。


2

你可以在 std::unique_ptr 上使用自定义删除器。

参考此问题


unique_ptr带有自定义删除器是很好的。但它只适用于某种单一资源,并且我需要在unique_ptr中关注T和Deleter类型。有时我想要一个“清理任务”,只需传递一个lambda函数来负责这个一次性作用域。 - Chen OT
1
嗯,我认为没有一个概念上干净的方法来做到这一点。我不知道你是否曾经写过C语言,但关键是,即使你为函数编写了单个退出点,函数的不同退出状态也需要以不同的方式处理。因此,在C++中,通常应确保在创建资源后自动处理它。如果您有一个释放许多东西的单个函数,则其中一些可能未初始化(例如,如果构造函数抛出异常),这可能会导致退出块中出现意外故障或复杂逻辑。 - midor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接