5.3.2014

C++11 Lambda Binding (Virtual Methods at Runtime)

Ich finde das gerade extrem spannend: einem in der funktionalen Programmierung erfahrenden Entwickler erzähle ich hier nichts Neues; würde ich den Grund nennen, warum mich dieses Konstrukt gerade so begeistert, würde ich meinen Arbeitsvertrag bei Steinberg übelst verletzen, weil ich dann Betriebsgeheimnisse ausplauderte (man beachte den Konjunktiv).

Wenn ich das richtig sehe, ist man wieder in den 90ern gelandet, wo die Parametrisierung via Funktionspointern eine Selbstverständlichkeit war. C++ Lambda = Pointer To Function? Genau das ist das – plus einigem Syntax-Sugar, wenn es darum geht, die Argumente durchzureichen (das „Caputure”-Feature in C++-Lambda ist mE. Sugar, nicht mehr – wie hilfreich das im konkreten Kontext auch ist).



Consider:
struct ITest { virtual ~ITest () {} virtual void out () const = 0; }; struct TestImpl : public ITest { TestImpl (const char* str) : str (str) {} void out () const override { printf (str); } const char* str; };
Usage:
ITest* test = new TestImpl ("Test"); test->out (); // => Test


Consider:
struct ITest { virtual ~ITest () {} virtual void out () const = 0; }; template <typename Call> struct TTest : public ITest { TTest (const Call& call) : call (call) {} void out () const override { call (); } private: const Call& call; }; template <typename Call> ITest* makeTest (const Call& call) { return new TTest<Call> (call); }
Usage:
ITest* test = makeTest ([]() { printf ("Lambda"); }); test->out (); // => Lambda


Consider (the fun starts here):
struct Test { void out () const { call (); } //--------- void setCall (Call _call) { call = _call; } private: std::function<void(void)> call; };
Usage:
Test* test = new Test; // no interface- or template magic needed test->setCall ([]() { printf ("Lambda runtime binding\n"); }); test->out (); // => Lambda runtime binding
(Kommentarfunktion z.Zt. deaktiviert.)