(no title)
raptorfactor | 9 months ago
https://github.com/es3n1n/defendnot/blob/master/defendnot-lo...
If you're curious what's actually going on there:
https://github.com/es3n1n/defendnot/blob/master/cxx-shared/s...
raptorfactor | 9 months ago
https://github.com/es3n1n/defendnot/blob/master/defendnot-lo...
If you're curious what's actually going on there:
https://github.com/es3n1n/defendnot/blob/master/cxx-shared/s...
chii|9 months ago
quietbritishjim|9 months ago
* auto means infer the type of this local variable from the expression after the =.
* Defer{} means default construct a Defer instance. Defer is an empty type, but it allows the % following it to call a specific function because...
* Defer has an overloaded operator%. It's a template function, which takes a callable object (type is the template parameter Callable) and returns a DeferHolder<Callable> instance.
* [&]()->void { /*code here*/ }; is C++ syntax for a lambda function that captures any variables it uses by address (that's the [&] bit), takes no parameters (that's the () bit) and returns nothing (that's the ->void bit). The code goes in braces.
* DeferHolder calls the function it holds when it is destroyed.
It's subjective but some (including me!) would say it's cursed because it's using a macro to make something that almost looks like C++ syntax but isn't quite. I'm pretty confident with C++ but I had no idea what was going on at first (except, "surely this is using macros somehow ... right?"). [Edit: After some thought, I think the most confusing aspect is that defer->void looks like a method call through an object pointer rather than a trailing return type.]
I'd say it would be better to just be honest about its macroness, and also just do the extra typing of the [&] each time so the syntax of the lambda is all together. (You could then also simplify the implementation.) You end up with something like this:
Or if you go all in with no args lambda, you could shorten it to:aa-jv|9 months ago
I personally don't find it that cursed, but for many old C++ heads this may be an overwhelming smell - adding a class to implement what should be a language feature may tweak some folks' ideology a bit too far.
eru|9 months ago
So you can abuse this mechanic to 'register' things to be executed at the end of the current scope, almost no matter how you exit the current scope.
es3n1n|9 months ago
es3n1n|9 months ago
gavinray|9 months ago
junon|9 months ago
I think the only bit I don't like personally is the syntax. I normally implement defer as a macro to keep things clean. If done correctly it can look like a keyword: `defer []{ something(); };`.
Asooka|9 months ago
fc417fc802|9 months ago
D (for example) has the concept of statements that trigger at end of scope built into the language.
drabbiticus|9 months ago
TL;DR, not AI
The code defers a function call until the point in time that an object goes out of scope. The implementation uses C macros to create a more succinct syntax that omits parts of the necessary C lambda/unnamed function definition and to create a unique variable name for managing the deferred function call. However, the resulting syntax eschews the common convention of using UPPER CASE to denote C macros, and instead appears similar at first glance to a function call from an object pointer.
This can cause confusion if one is not familiar with this pattern and expects macros to be communicated differently. Some commenters say this is common enough, or useful enough to them, to be considered almost idiomatic in some contexts.
For technical explanation, https://news.ycombinator.com/item?id=43959403#43960905 provides a useful breakdown of how the macro works.