0

There are several ways to pass callable objects as parameters or to store them for future use. You can create a class with operator(), you can define a function and pass a pointer to it, and, since C++11, you can define a lambda via [](){} syntax.

I appreciate lambda syntax as a shortcut in expressions such as find_if that often beg for a compact callable expression. What I don't understand about lambda is the desire to use them outside the point of their declaration and risk introducing dangling references and such. C++ already has a powerful way to pass callable objects around which is much safer then lambda, and in those situation there is no benefit of compact expression of lambda.

Thus the question: why does C++11 allow use of a lambda outside the function that declares is or the functions called from it (and therefore introduces the risk of dangling references, etc)? Could you give an example where keeping lambda live outside the declaring function would be desirable?

14
  • 6
    If lambdas weren't copyable, you wouldn't be able to use them with find_if Commented Feb 1, 2016 at 17:45
  • There are two sides of the story - first is why C++ allows them to be copyable - and this is simply so that they can be passed to algorithms, which accept their arguments by value. The other question is why some people abuse this and really make long-living copies of lambdas. That I do not know. Commented Feb 1, 2016 at 18:00
  • @SergeyA storing a long-living copy of a lambda for a call back seems fine to me. Do you consider that abuse of lambdas? Commented Feb 1, 2016 at 18:07
  • @Praetorian: changed the title to clarify. Commented Feb 1, 2016 at 18:08
  • 1
    @Michael what do you consider a safe alternative? You mention a powerful wat to pass callable objects around. What are you referring to? Commented Feb 1, 2016 at 18:12

2 Answers 2

1

Consider a function which is registered to be called when a future event occurs. It would be convenient to define it as a lambda, but it has to live beyond the scope in which it is defined:

for example

m_button->setOnClick(YOUR LAMBDA GOES HERE);
Sign up to request clarification or add additional context in comments.

Comments

1

What I don't understand about lambda is the desire to use them outside the point of their declaration and risk introducing dangling references and such. C++ already has a powerful way to pass callable objects around which is much safer then lambda, and in those situation there is no benefit of compact expression of lambda.

(1) Lambda isn't implicitly less safe than any other way of defining function objects. The way of passing a lambda is exactly the same as passing an instance of a named functor.

You can store references in a named functor, and you can capture references in a lambda. Storing a reference to a local object in either of those cases is a severe bug if the function object out lives the scope where those references were bound.

Whether the syntax of lambda is beneficial or not, is a matter of preference. I suppose, one could argue that because lambdas make the definition of functors simpler, it also makes the definition of broken functors simpler.

why does C++11 allow use of a lambda outside the function that declares is or the functions called from it (and therefore introduces the risk of dangling references, etc)?

Firstly, I imagine such semantic limitation would be hard to implement. You can't make them non-copyable because that would make them useless in standard algorithms.

Secondly, because storing a function object for later use is useful, see (2) and using lambdas isn't more dangerous than using instances of named functors, see (1).

Could you give an example where keeping lambda live outside the declaring function would be desirable?

(2) Just about any asynchronous callback situation. std::async, std::thread, GUI and other event systems. Callable function objects will be stored for later use in those situations and typically the objects do outlive the scope where they were created.

In general and also in this case, lambdas advantages over named functor types is that you get to place the function definition right where it's used. Well, you can never have the definition where it's actually used in a generic situation of asynchronous callbacks, but the point of registering the callback is as close as you can get.

The disadvantage of lambdas is their hard-for-humans-to-parse syntax that is an explosion of different brackets, braces and parenthesis. Again, this is matter of preference.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.