4 ms·
Here my C++ defer implementation https://twitter.com/stevemk14ebr/status/1347408381301190658?s=19 https://twitter.com/stevemk14ebr/status/1347408381301190658?..
by stevemk14ebr 6y ago
Here my C++ defer implementation https://twitter.com/stevemk14ebr/status/1347408381301190658?s=19 https://twitter.com/stevemk14ebr/status/1347408381301190658?...
- unscaled 6y agoBoost has had the BOOST_SCOPE_EXIT macro at least since Boost 1.38 (February 2009), a few months before the first public announcement of Go. Judging by the copyright, the earliest versions of this library (before acceptance into Boost) are from 2006, before Pike et. al. even started working on Go internally in Google. BOOST_SCOPE_EXIT in turn is based on Andrei Alexandrescu's pre-closure ScopeGuard implementation from 2000. Granted, both BOOST_SCOPE_EXIT and your defer macro work at block end, not function end, but I agree with OP that this is practically always the better approach, so I don't think we should look at this thing as C++ trying to copy go features with lousy hacks. It's probably the other way around, if anything. And modern implentations in C++ (like yours) are extremely straightforward.
- jerf 6y agoThe problem isn't that C++ can't do "defer"... the problem is that C++ can do everything, and all those "everythings" are constantly interacting because code bases will use all that "everything" fairly routinely. Just glancing at a particular defer implementation won't tell you how it interacts with everything else, let alone how it will interact with whatever strange things your own codebase has. Go's defer function is very predictable, not so much because Go's defer is magic but precisely because it isn't. There aren't a ton of features for it to interact with. This also isn't a special virtue of Go; IMHO it's a special (not unique, but unusual) failing of C++. It was insanely complicated already in the 90s and every standard since then has only made it worse.
- goalieca 6y agostd::shared_ptr<void> foo(nullptr, [&bar] (void*) { printf(":) %s\n", bar); }); the downside is having to write nullptr instead of just the closure. Something like this really should be part of the standard.
- sltkr 6y agoThat one executes deferred statements at end of scope, instead of on function exit. That doesn't work well if your defer-statement occurs in an if-body, for example. I don't think it's super valuable to mimic the Go syntax anyway. In C++ you can fairly easily implement a class that works like this, which is fairly clean and intuitive: void func() { Deferred deferred; for (int i = 0; i < 10; ++i) { deferred.push([] { some callback }); } // when Deferred is destroyed, it executes callbacks. } This is somewhat more powerful than Go's defer in that it gives the user explicit control over the scope. I think in Go you'd have to create a closure and call it immediately to create a nested scope for the purposes of executing deferred statements early.