14

Possible Duplicate:
Bind Vs Lambda?

My use of std::bind had dropped to 0 now that lambdas have gained wide support.

Are there any problems that std::bind is uniquely suited for over a lambda function?

Was there a compelling reason to keep std::bind in the standard once lambdas where added?

Community
  • 1
  • 1
deft_code
  • 57,255
  • 29
  • 141
  • 224

2 Answers2

21

You can capture by value or by reference, and the problem is that capture by value really means 'capture by copy'. This is a show stopper for a move-only type. So you can't use a lambda to do the following:

struct foo { void bar() {} };

std::unique_ptr<foo> f { new foo };
auto bound = std::bind(&foo::bar, std::move(f));
static_assert( std::is_move_constructible<decltype(bound)>::value, "" );
bound();

IIRC the Standard Committee briefly considered allowing arbitrary expression inside a lambda capture list to solve this (which could look like [std::move(f)] { return f.bar(); }), but I don't think there was a solid proposal and C++11 was already running late.

That and the restriction to monomorphic behaviour with lambdas are the deal breakers for me.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • 1
    Nice example! Does the `bind` object end up owning the dynamic `foo` object? Does it itself become non-copyable? – Kerrek SB Nov 11 '11 at 01:48
  • @KerrekSB Absolutely, on both accounts. – Luc Danton Nov 11 '11 at 01:52
  • @Luc great example, I was looking for exactly this. My remaining issue is that that bind expression can't be assigned to std::function. It can without the unique_ptr and the move though. Is there a way to pass that bind as a callback to another function? (The intention is that the callback owns the object, and deletes it once the callback itself is destroyed). – Joao da Silva Jan 25 '12 at 20:23
  • @Joao I have my own personal polymorphic function wrapper that, unlike `std::function`, doesn't require the types it wraps to be copy constructible but only that they be move constructible. AFAIK there's no solution available out of the box right now -- I remember some discussion for such a utility on the Boost mailing lists, but nothing has been written now. – Luc Danton Jan 26 '12 at 09:47
  • 9
    Move capture by lambda was added in C++14, so I think this point is now defunct ;-) – underscore_d Jan 01 '16 at 09:32
4

bind is great for creating references to bound member function:

Foo x;
auto f = std::bind(&Foo::bar, &x, 12, true);
register_callback(f);

Edit: As Luc Danton demonstrates, this construction is very flexible and allows for the instance pointer to come in a surprising variety of guises (e.g. smart pointers).[/]

If feasible, a lambda is probably preferable, especially since it offers greater potential for optimization, but bind-expressions still have their place.

(In any event, auto is preferable over std::function for the type to store the callable object.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 2
    bind is great but lambdas are better. This `auto f = [&x](){ return x.bar( 12, true ); };` is pretty succinct. So again, when would `std::bind` be preferred? – deft_code Nov 11 '11 at 01:17
  • @deft_code: Hmm... `bind` fills in the placeholders at the end (my `f` could still take plenty of arguments), so perhaps that's cleaner when the bind expression is part of a template somewhere. But it's a good question! – Kerrek SB Nov 11 '11 at 01:26
  • "If feasible, a lambda is probably preferable", indeed, the big advantage of lambdas is they can pick up static stuff statically while a bind picks up everything dynamically. This can often make the difference between a std::function storing the data internally and it being forced to turn to heap allocation. – plugwash Nov 21 '19 at 10:28