Live data from Hacker News

Lambda expression comparison between C++11, C++14 and C++17

maitesin.github.io

31–40 of 87 posts

Re: Lambda expression comparison between C++11, C++14 and C++17

#31
post #23

Another mildly obscure feature of lambdas is the ability to capture a variadic number of parameters. Example (slightly contrived): #include #include template void log(Args&&... args) { (std::cout std::future log_async(Args&&... args) { return std::async(std::launch::async, [args...] { log(args...); }); } int main() { auto f = log_async(1, 2, 3); f.wait(); }

For those of us still stuck on C++98 at work, would you mind explaining what's going on here? In particular, I can't figure out why the ellipsis is so separated from `args` here:

        (std::cout 
That looks like some black magic to me. The rest makes sense, I think.

Re: Lambda expression comparison between C++11, C++14 and C++17

#32
post #23

Another mildly obscure feature of lambdas is the ability to capture a variadic number of parameters. Example (slightly contrived): #include #include template void log(Args&&... args) { (std::cout std::future log_async(Args&&... args) { return std::async(std::launch::async, [args...] { log(args...); }); } int main() { auto f = log_async(1, 2, 3); f.wait(); }

For those of us still stuck on C++98 at work, would you mind explaining what's going on here? In particular, I can't figure out why the ellipsis is so separated from `args` here: (std::cout That looks like some black magic to me. The rest makes sense, I think.

http://en.cppreference.com/w/cpp/language/fold

Re: Lambda expression comparison between C++11, C++14 and C++17

#33
post #13
post #10

Taking a concept such as a lambda function and making it look this ugly...this is why I hate C++. I wish I wasn't forced to program it every day.

How is it ugly? The capture list is a necessary complexity in a language with manual memory management.

The only thing I find somewhat frustrating about the syntax is that the notation messes with my existing expectations. Up until now, in C-like languages a [] was just for collections and indexing into them, in the code I used at least.

I mean I'm not really complaining; I don't see better syntax to fit short anonymous functions into the existing syntax, without defeating the whole purpose of it either.

I suspect it's just a matter of getting used to this extra meaning for angular brackets.

Re: Lambda expression comparison between C++11, C++14 and C++17

#34
post #22

A question people who use C++ regularly, is C++ becoming easier to read and code?

Do you mean, becoming easier with new language features that get added?

Contrary to popular belief, new features can make a language more elegant and simple, if they make clunky old features obsolete with a simpler alternative.

Re: Lambda expression comparison between C++11, C++14 and C++17

#35
post #5

Earlier quoted context omitted.

Here take your rustwin point! I really like the explicit capture of C++'s lambdas more than the implicit one in most other languages (C#, Java, Python...) where you easily ends-up with a closure not referencing the expected variable. See: https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/clos...

I was burned by the same thing in Javascript. "Explicit is better than implicit". Therefore, I agree with you that explicit closure list, with the ability to copy and reference captured variables, is actually what C++ does right, not wrong.

The explicit capture list is only necessary in C++ because memory ownership and lifetimes are managed by the programmer in C++. Compare that to a garbage-collected language like Scheme or C#: when the implementation can figure out where memory needs to be freed and ensures you can't use-after-free, it frees the programmer from thinking about ownership (but not necessarily lifetimes: you can still wind up with memory leaks in GC'd languages if you're not careful to let go of references you no longer need). As mentioned elsewhere in this thread, Rust also offers the same level of explicit control without capture lists (though I'm on the fence about which way I prefer).

My point is that in languages with automatic memory management, explicit capture lists don't make much sense because the programmer is not tasked with managing memory and can safely capture references all the time. There's no need to ask oneself, "Do I own this pointed-to memory? Do I need to worry about it being freed before this closure? Should I make a copy?", etc. This is because, in a sense, the garbage collector itself owns the memory, but checks to make sure nothing else can use it anymore before it frees it.

Re: Lambda expression comparison between C++11, C++14 and C++17

#36
post #32

Earlier quoted context omitted.

For those of us still stuck on C++98 at work, would you mind explaining what's going on here? In particular, I can't figure out why the ellipsis is so separated from `args` here: (std::cout That looks like some black magic to me. The rest makes sense, I think.

http://en.cppreference.com/w/cpp/language/fold

Neat! Thank you :)

Re: Lambda expression comparison between C++11, C++14 and C++17

#38

Earlier quoted context omitted.

I was burned by the same thing in Javascript. "Explicit is better than implicit". Therefore, I agree with you that explicit closure list, with the ability to copy and reference captured variables, is actually what C++ does right, not wrong.

The explicit capture list is only necessary in C++ because memory ownership and lifetimes are managed by the programmer in C++. Compare that to a garbage-collected language like Scheme or C#: when the implementation can figure out where memory needs to be freed and ensures you can't use-after-free, it frees the programmer from thinking about ownership (but not necessarily lifetimes: you can still wind up with memory…

That is almost true, but there's one exception in those GC'ed languages due to the dichotomy of value types and reference types. The confusing behavior on capturing the iteration variable is one example.

Re: Lambda expression comparison between C++11, C++14 and C++17

#39
post #37
post #10

Taking a concept such as a lambda function and making it look this ugly...this is why I hate C++. I wish I wasn't forced to program it every day.

What would you propose as the syntax?

Apple extended C with block closures years ago.

  int b = 0;

  ^(int a) {
    return a*b;
  }
The declaration for lambda variables is almost identical to function pointers, just with a ^ instead of a *, so there's nothing to learn (or unlearn, like C++ forces you to). The ^ looks like a lambda, and historically the lambda of lambda calculus actually was a caret accent over the variable. The argument list can be elided.

Re: Lambda expression comparison between C++11, C++14 and C++17

#40
post #18

Earlier quoted context omitted.

Well, you need something to indicate the beginning of a lambda. So you can think of "[]" as serving that role, instead of "lambda" in Python or "\" in Haskell.

You can use C# fat arrow syntax, it even allows removing the braces for single expression lambdas which is the most common from anyway.

> removing the braces

If I have learned anything over the years, it's that removing the braces anywhere is the introduction of a bug during a rewrite waiting to happen.

Post reply on HN