Ich habe eine Klasse, die Callback-Funktionen registriert und sie später aufruft, die so aussieht.Erzeugen von Lambda aus der Klassenvorlage
template<typename ReturnType, typename... Args>
class Signal {
std::vector<std::function<ReturnType(Args...)>> function;
public:
template<typename... Args2>
ReturnType operator()(Args2&&... args2) {
ReturnType ret;
for (auto& func : function)
ret = func(std::forward<Args2>(args2)...);
return ret;
}
template<typename Func>
void func(Func const &func) {
function.push_back(std::function<ReturnType(Args...)>(func));
}
template<typename Class, typename Instance>
void mfunc(ReturnType(Class::*func)(Args...), Instance &instance) {
mfunc2(func, instance, make_int_sequence<sizeof...(Args)>{});
}
template<typename Class, typename Instance, int... I>
void mfunc2(ReturnType(Class::*func)(Args...), Instance &instance, int_sequence<I...>) {
using namespace std::placeholders;
function.push_back(std::function<ReturnType(Args...)>(std::bind(func, &instance, placeholder_template<I>{}...)));
}
};
#include <iostream>
class foo {
public:
int bar(int x, double y) {
std::cout << x << " and " << y << std::endl;
return x*2;
}
};
int main() {
foo foo1;
Signal<int, int, double> sig;
sig.mfunc(&foo::bar, foo1);
std::cout << "Return: " << sig(5,5.5) << std::endl;
}
hörte ich einen Vortrag von Stephan T. Lavavej heute, und eines der Dinge, die er zu sagen war, ist, dass std :: bind vermieden und stattdessen lambdas verwenden werden soll. Um etwas Neues zu lernen, dachte ich, ich würde versuchen, den Aufruf von std :: bind in mfunc2 zu einem Lambda zu ändern, aber ich bin ziemlich neu in Templates und kann nicht herausfinden, wie ich den gewünschten Code erzeuge.
Die aktuellen placeholder_template mit make_int_sequence ich hier auf SO gefunden, aber ich kann meinen Kopf nicht wirklich umschlingen, wie genau es funktioniert, oder wo auf sie jede gute Lektüre zu finden ...
Args ... enthält die Argumenttypen, die vom Lambda akzeptiert werden sollen, aber ich muss irgendwie Variablennamen wie var1, var2, var3 ect abhängig von der Größe von ... (Args) erstellen und sie dann zusammenführen.
Also zum Beispiel < int, int, int>, Args ... würde int, int halten. Ich mag dann das Lambda als
[func, &instance](int var1, int var2) -> ReturnType { return func(&instance, var1, var2); }
konstruieren Wie könnte ich dies zu erreichen?
Beginnen Sie bitte mit [mcve]. Mit etwas, das kompiliert, können wir Ihnen zeigen, wie man es ändert, um ein variadisches Lambda zu verwenden. – AndyG
Ich habe meinen Beitrag bearbeitet, um den Template Specifier zu entfernen, also sollte er jetzt kompilieren, solange Sie ihm einen Return-Typ (nicht void) und mindestens 1 Argument geben. – super