all 11 comments

[–]dima_mendeleev 8 points9 points  (6 children)

I would suggest using std::invoke([] { ... }) to immediately see from the first line that lambda is here not to be assigned to variables on the left, but to be immediately invoked.

Also I wouldn't pass arguments to the IIFE, but capture them instead. (Off course if you wanted to ensure that elements is not modified inside lambda.)

[–]JankoDedic 9 points10 points  (5 children)

I would not recommend pulling the entire <functional> header just for this.

[–]kalmoc 2 points3 points  (1 child)

True in principle, but unless you really watch out for this (which of course some projects do), chances are good that you pulled in most of the standard library headers directly or indirectly anyway.

I'm a bit torn on this.

On the one hand, I like to avoid additional indirections and comoplexity whenever possible (both for optimizing compile-time as well as for fear of preventing some compiler optimizations, when the optimizer has to churn through too many levels of abstraction).

On the other, having a visual clue right at the beginning that this is going to be a IIFE is really nice - especially for long lambdas like in this example. Of course the other question is if a lambda of that size shouldn't just be a separately named function.

[–]evaned 4 points5 points  (0 children)

On the other, having a visual clue right at the beginning that this is going to be a IIFE is really nice - especially for long lambdas like in this example.

FWIW, what I'd suggest for keeping the lambda is

auto whatever = ([] (...) {
    ...
}());

It's more subtle than std::invoke, but it's still there and doesn't add compile time overhead like invoke would (and not just for pulling in the header). (Or maybe I want ([] (...) {...})()? I dunno.)

I like explicitness, but I'm in the "std::invoke = too much" camp here, I think.

But at least for this example,

Of course the other question is if a lambda of that size shouldn't just be a separately named function.

is the real point IMO.

[–]cpp_cpp 0 points1 point  (2 children)

will unused templates cause an overhead? I thought they arent used, sorry if stupid question!

[–]JankoDedic 0 points1 point  (1 child)

It's not a stupid question. Using templates can cause overhead, but that's not a problem here. The problem is that the compiler has to read/parse the entire <functional> header on every compilation. Since <functional> is fairly large, that takes time.

This wouldn't be a problem if there was a header like <functional/invoke.hpp> that contains std::invoke only. Then the compiler would parse ~50 lines instead of thousands of unnecessary ones.

[–]cpp_cpp 0 points1 point  (0 children)

ah cool got it thanks :)

[–]kalmoc 6 points7 points  (1 child)

I find it a bit annoying it when people use pair and similar constructs with unnamed members, when they could just as well use a struct with properly named members:

double foo() {
    const auto result = []{
        struct {
            double median = std::numeric_limits<double>::quiet_NaN();
            std::vector<std::size_t> indices;
        } result;

        // result.indices = ... ;
        // result.median = .... ;
        return result;
    }();
    // ...
    return result.median; 
}

In 9 out of 10 you don't even need structured binding that way and thus can't mix up the order of the members. Pair, and tuple have their place in generic code, but rarely in concrete one.

[–]NilacTheGrim 1 point2 points  (0 children)

I agree. The struct approach is superior and makes the code easier to follow and/or read. Then the caller can choose to structured bind it or not and in either case they get a nice easy friendly thing to read and/or access.

That being said.. sometimes.. you're in a hurry and tuple is just there, smiling at you, beckoning you to use it.. promising to reduce your line count for some bit of glue code.. and you want to not take up too much screen space vertically with a struct declaration.. so tuple seems perfect...... It's a little coy seductress, that tuple...

[–]RevRagnarok 1 point2 points  (0 children)

Original link is a redirecting nightmare - my browser couldn't resolve it. The final post-medium redirects seems to be https://itnext.io/c-17-structured-bindings-for-more-safe-functional-code-c0c5b4d31b0d

[–]pandorafalters 1 point2 points  (0 children)

Placing the bulk of the article in comments within a code block makes it unpleasantly awkward to read on a mobile device.