C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Execute statement when leaving scope

From: Jason C <jason.cipriani_at_[hidden]>
Date: Mon, 12 Dec 2022 13:11:19 -0500
It is unclear to me what these proposals (both this new one and the
`scope_*` proposals) add that is not already trivially possible with code
in scoped object destructors.

Here are three of many other straightforward strategies. All may be fully
contained in the function they are in, even #3, if desired:
https://godbolt.org/z/9fWKhecrG

Most notably, imo:

struct generic_cleanup {
    explicit generic_cleanup (function<void()> cleanup) : cleanup(cleanup)
{ }
    ~generic_cleanup () { cleanup(); }
private:
    function<void()> cleanup;
};

void oneScopedCleanupStrategy () {

    // local vars must be declared before cleanup is declared, of course:
    int localvar;

    // fairly convenient syntax:
    generic_cleanup cleanup([&] {
        cout << "strategy3: scope cleanup " << localvar << endl;
    });

    // modifications to local vars will be visible to cleanup ([&])
    localvar = 900;

}

Nothing would prevent `generic_cleanup` from maintaining a list of cleanup
functions, either, if you'd like a more convenient syntax for building as
you go.

Full source follows signature.

Jason

#include <iostream>
#include <string>
#include <functional>
#include <memory>

using namespace std;

void strategy1 () {

    struct scope_cleanup {
        ~scope_cleanup () {
            cout << "strategy1: scope cleanup " << endl;
        }
    } cleanup;

    int localvar = 123; // however; scope_cleanup cannot access localvar

    cout << "strategy1: entered" << endl;

}

void strategy2 () {

    struct scope_cleanup_with_data {
        int localvar;
        ~scope_cleanup_with_data () {
            cout << "strategy2: scope cleanup " << localvar << endl;
        }
    } context;

    context.localvar = 123; // this provides a strategy for maintaining
data to be cleaned up

    cout << "strategy2: entered" << endl;

}

// a more general solution allowing a natural passing of local data
struct generic_cleanup {
    explicit generic_cleanup (function<void()> cleanup) : cleanup(cleanup)
{ }
    ~generic_cleanup () { cleanup(); }
private:
    function<void()> cleanup;
};

void strategy3 () {

    int localvar;

    generic_cleanup cleanup([&] {
        cout << "strategy3: scope cleanup " << localvar << endl;
    });

    cout << "strategy3: entered" << endl;
    localvar = 900;

}

int main () {

    const auto logcall = [](function<void()> callee, string name) {
        cout << name << ": calling" << endl;
        callee();
        cout << name << ": returned" << endl;
    };

    logcall(strategy1, "strategy1");
    logcall(strategy2, "strategy2");
    logcall(strategy3, "strategy3");

}







On Mon, Dec 12, 2022 at 10:00 AM Ville Voutilainen via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Mon, 12 Dec 2022 at 14:44, Jarrad Waterloo via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > Not to be dense, does that mean the following is slated for 23 or 26?
> >
> > scope_exit
> > scope_fail
> > scope_success
> > unique_resource
>
> Right now they're not being slated for either, because we don't (yet)
> have the proposal to move any of them
> into C++26. They certainly missed the train for C++23.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-12-12 18:11:47