An dieser Stelle ist es wichtig, sich mal function objects anzusehen, implementiert in boost.function und tr1 function. Zusammen mit tr1 bind, boost lambda bind, oder boost phoenix bind ein extremst mächtiges Werkzeug. Beispiel:
Code: Alles auswählen
void foo(int x, float y) {}
class X { void bar(string const &str, int i) {} };
class Functor { typedef int result_type; int operator()(float x) { return 42; } };
X x;
Functor functor;
function < void(int a, float b) > funcobj1 = bind(&foo, _1, _2);
funcobj1(5, 6); // ruft foo(5, 6) auf
function < void(string const &str, int i) > funcobj2 = bind(&X::bar, &x, _1, _2);
funcobj2("hello world", 1); // ruft x.bar("hello world", 1) auf
function < void(int i) > funcobj3 = bind(&X::bar, &x, "somefixedvalue", _1); // der 1. Parameter wird quasi fixiert; analog zum "Currying" bei funktionalen Sprachen
funcobj3(11); // ruft x.bar("somefixedvalue", 11) auf
function < int(float f) > funcobj4 = bind(&functor, _1);
funcobj4(4.1f); // ruft functor(4.1f) auf
Auf dieser Basis gestellt, werden signals deutlich einfacher. Hier ein boost.signals2 Beispiel:
Code: Alles auswählen
void foo(string const &str) { cout << str << endl; }
struct X { void bar(string const &str) { cout << str << endl; } };
X x;
signal < void(string const &somestr) > mysignal;
mysignal.connect(bind(&foo, _1));
mysignal.connect(bind(&X::bar, &x, _1));
mysignal("Hello world");