Earlier quoted context omitted.
Fully agree with what you're saying. Just a nitpick about bind (which I'm sure you're aware of, just for the sake of others). The return type of {boost,std}::bind is unspecified (it's basically just a "callable"). This means that bind doesn't have to do type erasure. On the other hand, {boost,std}::function has to do type erasure, which can boil down to a virtual function call. But that's orthogonal to where the call…
It's not type erasure per se, but it's somewhat functionally equivalent. When you pass a function pointer (or pointer to member function) to bind(), it has to store that pointer in a member variable and perform an indirect call in operator(). In theory this is something that a compiler should be able to optimize away, but in practice they very rarely actually do, so using bind() as the argument for a STL algorithm ty…
There really is quite a difference between what std::bind returns and a type-erasing class like std::function. For the latter, the type erasure may result in a virtual call that the optimizer has a hard time seeing through.
In practice, compilers are pretty good at optimizing bind. Here are some examples where lambda and bind generate identical code: https://godbolt.org/g/dQCSeG