38

Every time I need to use std::bind, I end up using a lambda instead. So when should I use std::bind? I just finished removing it from one codebase, and I found that lambdas were always simpler and clearer than std::bind. Isn't std::bind completely unnecessary? Shouldn't it be deprecated in the future? When should I prefer std::bind to lambda functions? (There has to be a reason that it got into the standard at the same time as lambdas.)

I've also noticed that more and more people are familiar with lambdas (so they know what lambdas do). However, a lot fewer people are familiar with std::bind and std::placeholders.

Alan
  • 1,166
  • 1
  • 9
  • 22
gnzlbg
  • 6,587
  • 3
  • 46
  • 94

2 Answers2

31

Here's something you can't do with a lambda:

std::unique_ptr<SomeType> ptr = ...;
return std::bind(&SomeType::Function, std::move(ptr), _1, _2);

Lambdas can't capture move-only types; they can only capture values by copy or by lvalue reference. Though admittedly this is a temporary issue that's being actively resolved for C++14 ;)

"Simpler and clearer" is a matter of opinion. For simple binding cases, bind can take a lot less typing. bind also is focused solely on function binding, so if you see std::bind, you know what you're looking at. Whereas if you use a lambda, you have to look at the lambda implementation to be certain of what it does.

Lastly, C++ does not deprecate things just because some other feature can do what it does. auto_ptr was deprecated because it is inherently dangerous to use, and there is a non-dangerous alternative.

Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829
  • 4
    +1. There appears to be an item in [Scott Meyers's upcoming book "Effective C++11"](http://scottmeyers.blogspot.cz/2013/01/effective-c11-content-and-status.html): "*Prefer lambdas to `std::bind`*". I do not have enough insight to comment on that, but if you could, that would be great. – Andy Prowl Mar 24 '13 at 13:01
  • Thanks for such a great answer! There is an article on capture by move: http://marcoarena.wordpress.com/2012/11/01/learn-how-to-capture-by-move/ Hopefully we'll get real capture by move in the next standard. – gnzlbg Mar 24 '13 at 13:02
  • 6
    C++-14 will fix this deficiency of lambdas. – David Schwartz Mar 04 '15 at 19:48
  • 6
    @AndyProwl most applicable is this brief quote from the book you cite: "...as of C++14, there are just no good use cases for [std::bind]" – Drew Dormann Mar 06 '15 at 20:46
  • 1
    While I think, that with c++14 you can probably replace std::bind completely with lambdas (and I mostly do) I still like your point about `std::bind` being less powerful and thus stating the intent more clearly. – MikeMB Mar 16 '15 at 12:46
24

You can create polymorphic objects with std::bind which you can't with lambdas, i.e. the call wrapper returned by std::bind can be invoked with different argument types:

#include <functional>
#include <string>
#include <iostream>

struct Polly
{
  template<typename T, typename U>
    auto operator()(T t, U u) const -> decltype(t + u)
    { return t + u; }
};

int main()
{
  auto polly = std::bind(Polly(), std::placeholders::_1, "confusing");

  std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;    
}

I created this as a puzzle not an example of good code, but it does demonstrate polymorphic call wrappers.

Jonathan Wakely
  • 153,269
  • 21
  • 303
  • 482
  • 17
    Yes, in C++14 this is equivalent to the bind expression: `[p = Polly{}](auto t) { return p(t, "confusing"); }` – Jonathan Wakely Nov 28 '14 at 09:18
  • 1
    @Elliot `Polly`'s `operator()` is clearly const, so I don't know what you mean. The code in the question compiles fine, and so does the lambda expression in my first comment above. – Jonathan Wakely Sep 02 '20 at 17:06
  • Apologies. I Stupidly missed the `const`. 'Should've looked closer before commenting. – Elliott Sep 03 '20 at 08:51