When used in conjunction with std::tr1::function, you can store the bind expression indefinitely, and then execute it at the proper time. For example, here is a crude runtime-configurable menu example:
#include <vector>
#include <functional>
#include <bind>
struct Document
{
Document() {}
Document* close() {delete this; return 0;}
Document* save() {return this;}
Document* print() {return this;}
private:
Document(const Document&);
Document& operator=(const Document&);
};
Document* new_doc() {return new Document;}
Document* open() {return new Document;}
int main()
{
// declare menu structure
std::vector<std::tr1::function<Document* ()> > menu(5);
Document* current_doc = 0;
using std::tr1::bind;
using std::tr1::ref;
// load menu call backs
menu[0] = new_doc;
menu[1] = open;
menu[2] = bind(&Document::close, ref(current_doc));
menu[3] = bind(&Document::save, ref(current_doc));
menu[4] = bind(&Document::print, ref(current_doc));
// exercise menu call backs
current_doc = menu[0](); // new
current_doc = menu[2](); // close
current_doc = menu[1](); // open
current_doc = menu[3](); // save
current_doc = menu[4](); // print
current_doc = menu[2](); // close
}
In this example a menu is represented by a vector of functions that take no parameters and return a Document*. Installed into this menu are both namespace scope functions, and member functions bound to the current document. std::tr1::function is smart enough to handle both function pointers and functors (and member functions too for that matter). In this case, we bind a pointer to the object we want with the member function we want to be executed before installing it into the menu. This results in a function object that takes no parameters and returns a Document*, just like the ordinary function pointers that are also installed into the menu.
The ref in the bind call stands for reference. This says that instead of bind storing a copy of the pointer current_doc in the bind expression, store a reference to the pointer. This is done so that as the value of current_doc changes throughout the demo, the document upon which the menu item acts is automatically updated. In general you can wrap any argument to bind in ref or cref (cref is for a const reference) when you would like to have bind operate on the actual argument instead of a copy of it.
Alternatively new_doc() and open() could have been static functions of Document. Then their installation into the menu would have looked like:
menu[0] = &Document::new_doc;
menu[1] = &Document::open;
If in the above example, an argument needed to be sent to all of the callbacks (or 2 or 3 arguments), that could easily be handled with placeholders:
Document* print(const std::string& printer_name)
{... return this;} ...
menu[4] = bind(&Document::print, ref(current_doc), _1);...
current_doc = menu[4]("color printer");
So bind is really handy. And when combined with the existing algorithms in <algorithm> and <numeric>, or when combined with the new std::tr1::function, bind becomes ultimately flexible, and absolutely indispensable.