std::function und member function
-
hallo leute
wie stelle ich es an das ich einer std::function eine member function zuweisen kann ?
moechte folgendes erreichen:using my_function = std::function<void(int, int)>; struct test { void func(int, int) { MessageBoxA(ß, "aufruf", "message", MB_OK); } }; int main(void) { test tt; my_function func = ... // tja was nun. dachte da an std::bind(&test::func, &tt) geht aber nicht func(0,0); }
wie geht das richtig ?
Meep Meep
-
Selbstverständlich wird
bind
nicht funktionieren, wenn du nicht entsprechende placeholder mitgibst:my_function func = std::bind(&test::func, &tt, std::placeholders::_1, std::placeholders::_2);
Ist jedoch mit Lambdas hübscher, und seit C++14 ganz besonders:
my_function func = [&] (auto... args) {return tt.func(args...);};
(Oder, wenn man flexibel bleiben möchte,
my_function func = [&] (auto&&... args) {return tt.func(std::forward<decltype(args)>(args)...);};
)
-
dank dir.
ich muss mir mal das bind zeugs zu gemuete fuehren.
da grausts mich jetzt schon
-
Meep Meep schrieb:
ich muss mir mal das bind zeugs zu gemuete fuehren.
da grausts mich jetzt schonDas ist nicht nötig, die zweite Variante ist besser. std::bind ist ein Überbleibsel aus alten Zeiten vor C++11 (wir ignorieren hier jetzt mal, dass es offiziell erst ab C++11 in die Standardbibliothek aufgenommen wurde). Inzwischen geht fast alles besser ohne bind, außer vielleicht in einigen Situationen mit variadic templates.
-
bind
brauchen wir dank Lambdas dafür nicht mehr. Es ist zwar kurz aufgeschrieben, kann aber tierisch nerven, wenn man es mit Überladung zu tun hat. Überlädst Dutt::func
, musst du nämlich den Typ von&tt::func
explizit erwähnen, damit der Compiler weiß, welchesfunc
Du meinst. Außerdem ist ein großer Nachteil vonstd::bind(&tt::func,...)
, dass die Information, welche Funktion ausgeführt werden soll, nicht mehr im Typ des bind-Ausdrucks vorhanden ist. Es ist ja nur ein Funktionszeiger. Du tust Dir damit keinen Gefallen, wenn Du so etwas in ein std::function<void(int,int)> reinstecken willst. Du hättest dann, wenn du dasfunction
-Objekt benutzt, unnötig viele "Funktionszeigersprünge" dabei.Mit nicht-generischen Lambdas (gibt es auch ab C++11), sähe das so aus:
my_function func = [&tt](int a, int b){ tt.func(a, b); };
Apropos Funktionszeiger: Die Programmiersprache Rust arbeitet da übrigens etwas anders. Dort ist der Typ des Äquivalents zu
&tt::func
einzigartig und bezieht sich auf die Funktion, was Inlining immer noch sehr einfach für den Compiler macht. Da braucht man keine Lambdas, nur um Inlining zu fördern.