A question people who use C++ regularly, is C++ becoming easier to read and code?
Absolutely, and without a doubt. * `unique_ptr` as a local variable. Before C++11, I needed to either (a) define a holder class for anything that should be deleted at the end of a scope or (b) delete it manually and pray that there isn't an exception thrown. Now, I can just declare it, and trust the destructor to clean up after me. * `unique_ptr` as a return value. Previously, if a function returns a pointer, there w…
Lambda expression comparison between C++11, C++14 and C++17
71–80 of 87 posts
Re: Lambda expression comparison between C++11, C++14 and C++17
#72Earlier quoted context omitted.
> I like the ability explicitly state what variables are being captured. Why? You state what variables are being captured by just using them in the lambda body.
> You state what variables are being captured by just using them in the lambda body. Wow, have you never spent a week debugging a JavaScript memory leak?
Re: Lambda expression comparison between C++11, C++14 and C++17
#73Earlier quoted context omitted.
I find that pointlessly pedantic. By the same measure, languages that don't offer bignums don't offer integers. Even Lisps need to implement closures in one way or another, and you may be surprised to see how they actually do it.
I think you miss the point, the OP was mentioning the property that in most languages, closures whose outer variables they are bringing into scope stay in scope (even if the outer function ends). In C++ they expire (is what I got from his comment, anyway).
Remember that C++ is a by value language. Pointers are explicit, fist class and distinct from the pointed to object.
References are werid, though.
Re: Lambda expression comparison between C++11, C++14 and C++17
#74Earlier quoted context omitted.
How is it ugly? The capture list is a necessary complexity in a language with manual memory management.
The syntax is not the prettiest, but it is legible once you understand what [](){} means. In C#, there is no such thing, but there is a part of me that wishes we had such a thing. I like the ability explicitly state what variables are being captured.
Re: Lambda expression comparison between C++11, C++14 and C++17
#75There is another interesting feature in C++17 for lambdas: Possibility to cast a lambda to a function pointer. It will become possible to store a lambda as a struct/member that could bind to "this" (like in Javascript).
I assume this is only for stateless lambdas, that have not captured anything? Because otherwise a function pointer would not be enough, right? Currently, any stateless lambda can decompose into a function pointer and be passed to any function that expects a function pointer, right? Are you saying that ++17 has augmented this, and if so can you provide more details or a reference (or an example) as I'm quite curious t…
It's the best reference I found. The paper only talks of capturing "*this" by value (as in the original post of the topic).
I think I read that in a draft about coroutines. The idea was to capture "this" by reference and convert the lambda to a function pointer to make it movable.
It would useful for delegates or signals too.
Re: Lambda expression comparison between C++11, C++14 and C++17
#76Earlier quoted context omitted.
Absolutely, and without a doubt. * `unique_ptr` as a local variable. Before C++11, I needed to either (a) define a holder class for anything that should be deleted at the end of a scope or (b) delete it manually and pray that there isn't an exception thrown. Now, I can just declare it, and trust the destructor to clean up after me. * `unique_ptr` as a return value. Previously, if a function returns a pointer, there w…
Re unique_ptr as a local variable: in C++98 you can use auto_ptr.
Re: Lambda expression comparison between C++11, C++14 and C++17
#77I love lambdas, but a lot of commenters are throwing around the word "closure" here, and c++ lambdas are definitely not closures. You can capture outside variables by value or by reference, but that value can expire before the lambda runs if the reference no longer exists; in which case, you are in trouble. Unlike a true closure (as in lisp or other languages), where the closed-over value stays around. If we talk onl…
Re: Lambda expression comparison between C++11, C++14 and C++17
#78Another 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
#79I love lambdas, but a lot of commenters are throwing around the word "closure" here, and c++ lambdas are definitely not closures. You can capture outside variables by value or by reference, but that value can expire before the lambda runs if the reference no longer exists; in which case, you are in trouble. Unlike a true closure (as in lisp or other languages), where the closed-over value stays around. If we talk onl…
I'm not familiar with closures from other languages. What about capturing a shared_ptr by value?
Re: Lambda expression comparison between C++11, C++14 and C++17
#80Earlier quoted context omitted.
Spores seem like an interesting solution. The language designer in me has a distaste for it, though :p For case 1 (capture of mutable references), an explicit copy operator might be better (as in, "I want whatever value this variable is bound to, rather than the storage location") (or even vice versa, where value is the default and there's an operator for location). In a way, spores accomplish this by forcing you to…
Agree on the copy operator, not only for spores, have wanted it more than one time in other languages too. Not sure how the this binding should work though. If calling a method you need to a) dispatch on the runtime type and b) provide the instance to the method when called.
I think when a programmer writes "foo.combobulate()", the vast majority of the time, the intend to capture "foo". If they didn't and were being clever, I don't think it's unreasonable for the compiler to expect them to be explicit and write "this.foo.combobulate()" instead. In the former case, the compiler creates the implicit binding to capture, in the latter it does nothing implicit and just closes over "this".
I'm certain that the compiler has enough information to do this, and that it's in accordance with the principle of least surprise ;)