3

We have some resource, which need to be manually released. Except explicitly writing a RAII wrapper for managing its resource, is any built-in template or class in std library to automatically perform a lambda task?

{
    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

The class may behavior like the following, but I am wondering that wheel may be already built in std library, or I should write my own one.

struct GuardedTask
{
    std::function<void()> task;
    GuardedTask(std::function<void()> f): task(f) {}
    ~GuardedTask(){ task(); }
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
Chen OT
  • 3,486
  • 2
  • 24
  • 46

2 Answers2

3

This pattern is called a scope guard and has many other uses than RAII cleanup such as transaction safe functions. Unfortunately, there is no standardized scope guard but there is proposal P0052 that intended to implement this.

user975989
  • 2,578
  • 1
  • 20
  • 38
2

You could use a custom deleter on std::unique_ptr.

Cf this question.

Community
  • 1
  • 1
midor
  • 5,487
  • 2
  • 23
  • 52
  • The unique_ptr with custom deleter is good. But it is useful for kind of single resource, and I need care the T and Deleter Type in unique_ptr. Sometimes I want a "Clean Task" just in charge for this one-time scope, by simply passing a lambda. – Chen OT Mar 30 '17 at 07:45
  • 1
    Hm, I don't think there is a conceptually clean way to do that. I don't know if you have ever written C, but the crux is, even if you write a single exit point for a function, the different exit states of the function need to be handled differently. Thus, in C++, you should usually ensure that a resource is handled automatically after it's creation. If you have a single function to free up many things, some of them may not be initialized (e.g. if a constructor throws), which may lead to surprising failures in your exit block, or to complicated logic. – midor Mar 30 '17 at 08:09