c++raiic++23

Defer a lambda in C++23


I like using the latest C++ for personal projects. I was wondering how I can defer lambdas (or use a scopeguard) in the latest C++

Below is a quick implementation. I like style 3 the best. Does the standard have anything like the below? Do I have any extremely obvious bugs with this? I only spent a few minutes writing this

#include<cstdio>
#include<memory>
using namespace std;

template<class T>
class DeferLambda {
    T l;
public:
    DeferLambda(T l) : l(l) { }
    ~DeferLambda() { l(); }
};

auto make_defer(auto p) -> DeferLambda<decltype(p)> { return {p}; }

#define NAME2(A, B) A ## B
#define NAME(A, B) NAME2(A, B)
#define L(X) auto NAME(defer, __LINE__) = make_defer(X);
int main(int argc, char *argv[])
{
    DeferLambda a([]{puts("Style 1");});
    auto b = make_defer([]{puts("Style 2");});
    L([]{puts("Style 3");});
    puts("test");
}

Solution

  • Does the standard have anything like the below?

    Not as a built-in language feature, so creating a class and adding a user-defined destructor to it like you've done is how it has to be done. There are many variations on that theme, like std::experimental::scope_exit, which is not in the standard library, but has been proposed to be included.

    Do I have any extremely obvious bugs with this?

    It depends on what you're after. If this is to be used as some kind of "finally" at the end of scopes, then you may want to delete the ability to copy your DeferLambdas. Otherwise, someone may end up with two of these things, doing the same operation when they go out of scope.