#include <functional>
class Button
{
// Allgemeines Ding, das sich wie eine Funktion verhält, die void zurück gibt und keine Parameter hat:
std::function<void()> f;
public:
// Akzeptiert alles, was sich irgendwie void()-artig aufrufen lässt:
template <typename T> void set_function(T t) { f = t; }
void invoke_function()
{
f();
}
};
// von hier an dient alles nur der Demonstration:
#include <iostream>
using std::cout;
void void_funktion_ohne_parameter() { cout << "void_funktion_ohne_parameter\n"; }
void void_funktion_mit_parameter(int i) { cout << "void_funktion_mit_parameter: " << i << '\n'; }
struct Foo
{
void nicht_statische_memberfunktion_ohne_parameter() { cout << "nicht_statische_memberfunktion_ohne_parameter\n"; }
void nicht_statische_memberfunktion_mit_parameter(int i) { cout << "nicht_statische_memberfunktion_mit_parameter: " << i << '\n'; }
static void statische_memberfunktion() { cout << "Langweilig!\n"; }
};
struct Functor
{
void operator()() { cout << "Functor\n"; }
};
int main()
{
using std::bind;
Button button;
button.set_function(void_funktion_ohne_parameter); // Bei freien Funktionen kann man den Adressoperator auch weglassen
button.invoke_function();
button.set_function(bind(void_funktion_mit_parameter, 5));
button.invoke_function();
Foo foo;
button.set_function(bind(&Foo::nicht_statische_memberfunktion_ohne_parameter, &foo)); // Bei Memberfunktionen ist der Adressoperator nötig
button.invoke_function();
button.set_function(bind(&Foo::nicht_statische_memberfunktion_mit_parameter, &foo, 5));
button.invoke_function();
button.set_function(Foo::statische_memberfunktion); // Statische Memberfunktionen sind auch nicht anders als freie Funktionen mit besonderem Namen.
button.invoke_function();
button.set_function(Functor()); // ALLES was irgendwie wie void() aufrufbar ist funktioniert
button.invoke_function();
button.set_function([](){cout<<"Lambda\n";}); // Das ist insbesondere praktisch für Lambdas
button.invoke_function();
}