Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the shortest path in C++11 (or newer) to create an RAII wrapper without having to write a new class?

Often I'm in a situation where I need a simple RAII wrapper, but I wouldn't want to create a whole new class for this for many reasons including time constraints and organization problems. My quick-n-dirty solution is the following.

Say I want to make sure that by the end of the scope, I want a boolean to switch back to its original state:

bool prevState = currState;
currState      = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
    currState = prevState;
    delete p;
});

This solution works fine, but the dirty part is the necessity to allocate and deallocate that integer just to make unique_ptr work and call the custom destructor at destruction.

Is there a cleaner way to do this without having to write a whole class, and get rid of the new for the dummy int?

like image 647
The Quantum Physicist Avatar asked Dec 12 '18 09:12

The Quantum Physicist


2 Answers

You can use BOOST_SCOPE_EXIT

auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
     currState = prevState;
} BOOST_SCOPE_EXIT_END
like image 199
user7860670 Avatar answered Nov 01 '22 21:11

user7860670


A little bit better than yours: You can use &prevState in the custom destructor without deleting it, so you do not need to new and delete something:

void foo(bool & currState, bool newState)
{
    bool prevState = currState;
    currState      = newState;
    std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
        currState = prevState;
    });
    cout << "currState: " << currState << endl;
}

You also forgot to capture currState in the lambda.

Here is an example: https://ideone.com/DH7vZu

like image 20
mch Avatar answered Nov 01 '22 22:11

mch