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












9














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?










share|improve this question




















  • 1




    Not sure you need to allocate anything?
    – Matthieu Brucher
    Dec 12 '18 at 9:37






  • 2




    What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:41






  • 1




    @TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:44








  • 1




    @πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
    – The Quantum Physicist
    Dec 12 '18 at 9:45








  • 1




    @TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:48
















9














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?










share|improve this question




















  • 1




    Not sure you need to allocate anything?
    – Matthieu Brucher
    Dec 12 '18 at 9:37






  • 2




    What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:41






  • 1




    @TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:44








  • 1




    @πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
    – The Quantum Physicist
    Dec 12 '18 at 9:45








  • 1




    @TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:48














9












9








9


1





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?










share|improve this question















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?







c++ c++11 c++14 c++17 raii






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 12 '18 at 10:01









πάντα ῥεῖ

71.8k972134




71.8k972134










asked Dec 12 '18 at 9:35









The Quantum Physicist

11.4k64596




11.4k64596








  • 1




    Not sure you need to allocate anything?
    – Matthieu Brucher
    Dec 12 '18 at 9:37






  • 2




    What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:41






  • 1




    @TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:44








  • 1




    @πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
    – The Quantum Physicist
    Dec 12 '18 at 9:45








  • 1




    @TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:48














  • 1




    Not sure you need to allocate anything?
    – Matthieu Brucher
    Dec 12 '18 at 9:37






  • 2




    What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:41






  • 1




    @TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:44








  • 1




    @πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
    – The Quantum Physicist
    Dec 12 '18 at 9:45








  • 1




    @TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:48








1




1




Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37




Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37




2




2




What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41




What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41




1




1




@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44






@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44






1




1




@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45






@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45






1




1




@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48




@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48












4 Answers
4






active

oldest

votes


















6














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






share|improve this answer





















  • This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
    – The Quantum Physicist
    Dec 12 '18 at 9:53










  • Interesting solution for the problem.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:59






  • 1




    I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
    – Daniel Langr
    Dec 12 '18 at 10:11








  • 1




    @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
    – Daniel Langr
    Dec 12 '18 at 11:57






  • 1




    @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
    – The Quantum Physicist
    Dec 12 '18 at 12:12



















7














You can use BOOST_SCOPE_EXIT



auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END





share|improve this answer

















  • 2




    Yay. Boost. :-/
    – Johannes Overmann
    Dec 12 '18 at 23:16



















0














Don't use std::function. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz

If you absolutely don't want to use any external class or function, do below:



bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}


If you are ok with a little reusable function, below works. This abstracts the unused void*.



C++14 or later



template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}

bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}





share|improve this answer































    0














    How about gsl::finally? Library is not so heavy as boost and finally does not use std::function, so can be easly inlined. Also no dynamic allocation of std::unique_ptr



    using namespace std;

    void foo(bool & currState, bool newState)
    {
    auto revertState = gsl::finally([prevState = currState, &currState]{
    currState = prevState;
    });
    currState = newState;
    cout << "currState: " << currState << endl;
    }


    int main() {
    bool state = false;
    foo(state, true);
    cout << "state: " << state << endl;
    return 0;
    }


    Online example: https://ideone.com/Xi1izz (with copied gsl::finally, since #include <gsl/gsl> is not available here)






    share|improve this answer





















    • Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
      – The Quantum Physicist
      Dec 15 '18 at 11:46











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739994%2fwhats-the-shortest-path-in-c11-or-newer-to-create-an-raii-wrapper-without-h%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    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






    share|improve this answer





















    • This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
      – The Quantum Physicist
      Dec 12 '18 at 9:53










    • Interesting solution for the problem.
      – πάντα ῥεῖ
      Dec 12 '18 at 9:59






    • 1




      I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
      – Daniel Langr
      Dec 12 '18 at 10:11








    • 1




      @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
      – Daniel Langr
      Dec 12 '18 at 11:57






    • 1




      @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
      – The Quantum Physicist
      Dec 12 '18 at 12:12
















    6














    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






    share|improve this answer





















    • This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
      – The Quantum Physicist
      Dec 12 '18 at 9:53










    • Interesting solution for the problem.
      – πάντα ῥεῖ
      Dec 12 '18 at 9:59






    • 1




      I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
      – Daniel Langr
      Dec 12 '18 at 10:11








    • 1




      @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
      – Daniel Langr
      Dec 12 '18 at 11:57






    • 1




      @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
      – The Quantum Physicist
      Dec 12 '18 at 12:12














    6












    6








    6






    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






    share|improve this answer












    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







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 12 '18 at 9:45









    mch

    5,12921632




    5,12921632












    • This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
      – The Quantum Physicist
      Dec 12 '18 at 9:53










    • Interesting solution for the problem.
      – πάντα ῥεῖ
      Dec 12 '18 at 9:59






    • 1




      I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
      – Daniel Langr
      Dec 12 '18 at 10:11








    • 1




      @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
      – Daniel Langr
      Dec 12 '18 at 11:57






    • 1




      @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
      – The Quantum Physicist
      Dec 12 '18 at 12:12


















    • This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
      – The Quantum Physicist
      Dec 12 '18 at 9:53










    • Interesting solution for the problem.
      – πάντα ῥεῖ
      Dec 12 '18 at 9:59






    • 1




      I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
      – Daniel Langr
      Dec 12 '18 at 10:11








    • 1




      @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
      – Daniel Langr
      Dec 12 '18 at 11:57






    • 1




      @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
      – The Quantum Physicist
      Dec 12 '18 at 12:12
















    This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
    – The Quantum Physicist
    Dec 12 '18 at 9:53




    This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
    – The Quantum Physicist
    Dec 12 '18 at 9:53












    Interesting solution for the problem.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:59




    Interesting solution for the problem.
    – πάντα ῥεῖ
    Dec 12 '18 at 9:59




    1




    1




    I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
    – Daniel Langr
    Dec 12 '18 at 10:11






    I would just note that this solution might not be the most efficient one, since std::function applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
    – Daniel Langr
    Dec 12 '18 at 10:11






    1




    1




    @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
    – Daniel Langr
    Dec 12 '18 at 11:57




    @TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
    – Daniel Langr
    Dec 12 '18 at 11:57




    1




    1




    @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
    – The Quantum Physicist
    Dec 12 '18 at 12:12




    @DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
    – The Quantum Physicist
    Dec 12 '18 at 12:12













    7














    You can use BOOST_SCOPE_EXIT



    auto prevState{currState};
    currState = newState;
    BOOST_SCOPE_EXIT(&currState, &prevState)
    {
    currState = prevState;
    } BOOST_SCOPE_EXIT_END





    share|improve this answer

















    • 2




      Yay. Boost. :-/
      – Johannes Overmann
      Dec 12 '18 at 23:16
















    7














    You can use BOOST_SCOPE_EXIT



    auto prevState{currState};
    currState = newState;
    BOOST_SCOPE_EXIT(&currState, &prevState)
    {
    currState = prevState;
    } BOOST_SCOPE_EXIT_END





    share|improve this answer

















    • 2




      Yay. Boost. :-/
      – Johannes Overmann
      Dec 12 '18 at 23:16














    7












    7








    7






    You can use BOOST_SCOPE_EXIT



    auto prevState{currState};
    currState = newState;
    BOOST_SCOPE_EXIT(&currState, &prevState)
    {
    currState = prevState;
    } BOOST_SCOPE_EXIT_END





    share|improve this answer












    You can use BOOST_SCOPE_EXIT



    auto prevState{currState};
    currState = newState;
    BOOST_SCOPE_EXIT(&currState, &prevState)
    {
    currState = prevState;
    } BOOST_SCOPE_EXIT_END






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 12 '18 at 9:41









    VTT

    23.8k42345




    23.8k42345








    • 2




      Yay. Boost. :-/
      – Johannes Overmann
      Dec 12 '18 at 23:16














    • 2




      Yay. Boost. :-/
      – Johannes Overmann
      Dec 12 '18 at 23:16








    2




    2




    Yay. Boost. :-/
    – Johannes Overmann
    Dec 12 '18 at 23:16




    Yay. Boost. :-/
    – Johannes Overmann
    Dec 12 '18 at 23:16











    0














    Don't use std::function. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz

    If you absolutely don't want to use any external class or function, do below:



    bool foo_2() {
    bool f = false;
    auto eos = [&](void*){
    f = true;
    };
    std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
    return f;
    }


    If you are ok with a little reusable function, below works. This abstracts the unused void*.



    C++14 or later



    template<class F>
    auto call_at_end_of_scope(F&& f){
    auto eos = [f{std::forward<F>(f)}](void*){f();};
    return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
    }

    bool foo_3() {
    bool f = false;
    auto handle = call_at_end_of_scope([&](){
    f = true;
    });
    return f;
    }





    share|improve this answer




























      0














      Don't use std::function. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz

      If you absolutely don't want to use any external class or function, do below:



      bool foo_2() {
      bool f = false;
      auto eos = [&](void*){
      f = true;
      };
      std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
      return f;
      }


      If you are ok with a little reusable function, below works. This abstracts the unused void*.



      C++14 or later



      template<class F>
      auto call_at_end_of_scope(F&& f){
      auto eos = [f{std::forward<F>(f)}](void*){f();};
      return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
      }

      bool foo_3() {
      bool f = false;
      auto handle = call_at_end_of_scope([&](){
      f = true;
      });
      return f;
      }





      share|improve this answer


























        0












        0








        0






        Don't use std::function. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz

        If you absolutely don't want to use any external class or function, do below:



        bool foo_2() {
        bool f = false;
        auto eos = [&](void*){
        f = true;
        };
        std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
        return f;
        }


        If you are ok with a little reusable function, below works. This abstracts the unused void*.



        C++14 or later



        template<class F>
        auto call_at_end_of_scope(F&& f){
        auto eos = [f{std::forward<F>(f)}](void*){f();};
        return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
        }

        bool foo_3() {
        bool f = false;
        auto handle = call_at_end_of_scope([&](){
        f = true;
        });
        return f;
        }





        share|improve this answer














        Don't use std::function. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz

        If you absolutely don't want to use any external class or function, do below:



        bool foo_2() {
        bool f = false;
        auto eos = [&](void*){
        f = true;
        };
        std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
        return f;
        }


        If you are ok with a little reusable function, below works. This abstracts the unused void*.



        C++14 or later



        template<class F>
        auto call_at_end_of_scope(F&& f){
        auto eos = [f{std::forward<F>(f)}](void*){f();};
        return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
        }

        bool foo_3() {
        bool f = false;
        auto handle = call_at_end_of_scope([&](){
        f = true;
        });
        return f;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 12 '18 at 15:27

























        answered Dec 12 '18 at 11:38









        balki

        11k1760107




        11k1760107























            0














            How about gsl::finally? Library is not so heavy as boost and finally does not use std::function, so can be easly inlined. Also no dynamic allocation of std::unique_ptr



            using namespace std;

            void foo(bool & currState, bool newState)
            {
            auto revertState = gsl::finally([prevState = currState, &currState]{
            currState = prevState;
            });
            currState = newState;
            cout << "currState: " << currState << endl;
            }


            int main() {
            bool state = false;
            foo(state, true);
            cout << "state: " << state << endl;
            return 0;
            }


            Online example: https://ideone.com/Xi1izz (with copied gsl::finally, since #include <gsl/gsl> is not available here)






            share|improve this answer





















            • Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
              – The Quantum Physicist
              Dec 15 '18 at 11:46
















            0














            How about gsl::finally? Library is not so heavy as boost and finally does not use std::function, so can be easly inlined. Also no dynamic allocation of std::unique_ptr



            using namespace std;

            void foo(bool & currState, bool newState)
            {
            auto revertState = gsl::finally([prevState = currState, &currState]{
            currState = prevState;
            });
            currState = newState;
            cout << "currState: " << currState << endl;
            }


            int main() {
            bool state = false;
            foo(state, true);
            cout << "state: " << state << endl;
            return 0;
            }


            Online example: https://ideone.com/Xi1izz (with copied gsl::finally, since #include <gsl/gsl> is not available here)






            share|improve this answer





















            • Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
              – The Quantum Physicist
              Dec 15 '18 at 11:46














            0












            0








            0






            How about gsl::finally? Library is not so heavy as boost and finally does not use std::function, so can be easly inlined. Also no dynamic allocation of std::unique_ptr



            using namespace std;

            void foo(bool & currState, bool newState)
            {
            auto revertState = gsl::finally([prevState = currState, &currState]{
            currState = prevState;
            });
            currState = newState;
            cout << "currState: " << currState << endl;
            }


            int main() {
            bool state = false;
            foo(state, true);
            cout << "state: " << state << endl;
            return 0;
            }


            Online example: https://ideone.com/Xi1izz (with copied gsl::finally, since #include <gsl/gsl> is not available here)






            share|improve this answer












            How about gsl::finally? Library is not so heavy as boost and finally does not use std::function, so can be easly inlined. Also no dynamic allocation of std::unique_ptr



            using namespace std;

            void foo(bool & currState, bool newState)
            {
            auto revertState = gsl::finally([prevState = currState, &currState]{
            currState = prevState;
            });
            currState = newState;
            cout << "currState: " << currState << endl;
            }


            int main() {
            bool state = false;
            foo(state, true);
            cout << "state: " << state << endl;
            return 0;
            }


            Online example: https://ideone.com/Xi1izz (with copied gsl::finally, since #include <gsl/gsl> is not available here)







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 15 '18 at 11:09









            R2RT

            957511




            957511












            • Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
              – The Quantum Physicist
              Dec 15 '18 at 11:46


















            • Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
              – The Quantum Physicist
              Dec 15 '18 at 11:46
















            Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
            – The Quantum Physicist
            Dec 15 '18 at 11:46




            Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
            – The Quantum Physicist
            Dec 15 '18 at 11:46


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739994%2fwhats-the-shortest-path-in-c11-or-newer-to-create-an-raii-wrapper-without-h%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Quarter-circle Tiles

            build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

            Mont Emei