So konvertieren Sie einen lambda-Ausdruck, um ein std::function mit Vorlagen
Im Grunde, was ich möchte in der Lage sein zu tun ist, nehmen Sie einen lambda-Ausdruck mit einer beliebigen Anzahl von jedem Typ der Parameter und konvertieren es in ein std::function.
Ich habe versucht, die folgenden und weder Methode funktioniert.
std::function([](){});//Complains that std::function is missing template parameters
template <typename T> void foo(function<T> f){}
foo([](){});//Complains that it cannot find a matching candidate
Dem folgenden code funktioniert doch, aber es ist nicht das, was ich will, da es erfordert die explizite Angabe der template-Parameter, die nicht für generischen code.
std::function<void()>([](){});
Ich habe mucking herum mit Funktionen und Vorlagen, die den ganzen Abend und ich kann einfach nicht herausfinden, so dass jede Hilfe wäre sehr geschätzt werden.
Wie bereits erwähnt in einem Kommentar, der Grund, warum ich versuche, dies zu tun ist, weil ich bin versucht zu implementieren currying in C++ mithilfe von variadic templates. Leider scheitert schrecklich, wenn mit lambdas. Ich kann zum Beispiel passieren eine standard-Funktion über einen Funktionszeiger.
template <typename R, typename...A>
void foo(R (*f)(A...)) {}
void bar() {}
int main() {
foo(bar);
}
Jedoch kann ich nicht herausfinden, wie man einen lambda-Ausdruck übergeben, um so eine Variable Funktion. Warum bin ich interessiert bei der Umwandlung eine generische lambda in einem std::function ist, weil ich Folgendes tun können, aber es endet zu verlangen, dass ich ausdrücklich die template-Parameter std::function, die ist, was ich versuche zu vermeiden.
template <typename R, typename...A>
void foo(std::function<R(A...)>) {}
int main() {
foo(std::function<void()>([](){}));
}
struct foo { void operator()(int); void operator()(std::string); };
. Wie würden Sie die Idee für diese Arbeit?Was wollen Sie erreichen? Könnte Ihnen zeigen, einige pseudo-code?
Ich war eigentlich versucht zu implementieren currying in C++, aber wenn ich dann versucht, Rückschlüsse auf die Parameter eines lambda-mithilfe von variadic templates, alles brach zusammen. Also ich hatte gehofft, wenn ich könnte einfach konvertieren die lambda ein std::function, meine Probleme würden gelöst werden.
Übrigens, sind Sie vertraut mit
std::bind
?Ich glaube nicht, dass dieses feature implementiert werden können in einer generischen Art und Weise. Betrachten Sie eine Struktur mit mehreren
operator ()
s Annahme von unterschiedlichen argument-Typen. Welche Art von std::function
sollte es passen?InformationsquelleAutor retep998 | 2012-11-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie können nicht passieren Sie eine lambda-Funktion-Objekt als argument vom Typ
std::function<T>
ohne explizite Angabe der template-argumentT
. Vorlage Typ Abzug versucht, die Art Ihrer lambda-Funktion, um diestd::function<T>
die es einfach nicht können in diesem Fall - diese Typen sind nicht das gleiche. Vorlage Typ Abzug berücksichtigt nicht die Konvertierungen zwischen Typen.Es ist möglich, wenn Sie können es auf eine andere Weise abzuleiten, die Typ. Sie können dies tun, indem er die Funktion als argument in einer
identity
- Typ, so dass es nicht scheitern, der versucht, die lambdastd::function
(weil die abhängigen Typen sind einfach ignoriert von Typ-Abzug) und geben einige andere Argumente.Dies ist offensichtlich nicht hilfreich in Ihrer situation, obwohl, weil Sie nicht möchten, übergeben Sie die Werte erst später.
Da Sie nicht wollen, geben Sie den template-Parameter, noch wollen Sie andere Argumente übergeben, aus dem die template-Parameter abgeleitet werden können, wird der compiler nicht in der Lage sein, Rückschlüsse auf die Art Ihrer
std::function
argument.Mist. Ich dachte, es wird eindeutig sein, da Lambda-Ausdrücke haben nur eine
op()
.InformationsquelleAutor Joseph Mansfield
Können Sie eine engagierte/Retrospektive cast. Sobald Sie ein tool wie dieses
kann man sagen
FFL()
alle lambda-Arten zu haben Sie umgewandelt, was wäre die richtige version vonstd::function
Anzeigen
Callback
:template <typename... Args>
auto parameter_grinding_callback(std::function<void(Args...)> f) -> decltype(f)
kann man dann schreiben:auto omg = parameter_grinding_callback(FFL([](int a){std::cout << a << std::endl;}));
omg(5);
InformationsquelleAutor Nikos Athanasiou
Siehe Herleitung der Anruf Unterschrift eines lambda-oder beliebig abrufbar für "make_function", Sie können ableiten, die Berufung Unterschrift des lambda (oder jede andere Funktor mit einem einzigen Aufruf die Unterschrift) von seiner (einzigen)
operator()
:Dies ist eine eher unflexible Ansatz, obwohl; R. Martinho Fernandes sagt, es nicht für die Arbeit funktoren mit mehreren
operator()
s, noch für funktoren mit Vorlagenoperator()
oder für (C++14) polymorphe Lambda-Ausdrücke. Dies ist der Grund, warumbind
verzögert Inferenz des Ergebnisses geben, bis die eventuellen Anruf versuchen.InformationsquelleAutor ecatmur
Ist es möglich, die benötigten std::function-Typ für lambda mit Ableitung, decltype, variadic-templates und ein paar Merkmale Typ:
Ich es in meinem code wie folgt:
ambient::lambda([&](const vector<int>& val){
//some code here //
})(a);
PS: in meinem realen Fall, den ich dann speichern Sie diese std::function Objekt und seine Argumente innerhalb einer generischen kernel-Objekte, die ich ausführen kann später auf Nachfrage über virtuelle Funktionen.
InformationsquelleAutor Alex Kosenkov
Nicht currying bereits umgesetzt mit
std::bind
?cout<<curry([](int x, int y){return x*y;})(5)(7);
. Ich weiß schon, wie die Verwendung von std::bind und habe es ausgiebig vor. Das problem auf der anderen Seite ist es einfach eine Herausforderung um zu sehen, was ich erreichen kann mit variadic templates.in deinem Beispiel-code, Ihren lambda fängt nichts und daher ist umwandelbar zu einem Funktionszeiger. Ich gehe davon aus, dass Sie nicht wollen eine Lösung, die basiert auf, der?
Das ist richtig.
Wohl
std::bind
ist teilweise Anwendung (unter anderem) verwendet. Es ist eine überschneidung in dem, was beide currying und partielle Anwendung sind nützlich für die, wenn.Hinweis:
InformationsquelleAutor xtofl
Dies könnte interessant für Sie sein: https://gist.github.com/Manu343726/94769034179e2c846acc
Dass ist ein experiment, das ich geschrieben habe, vor einem Monat. Das Ziel war die Erstellung einer Funktor-wie C++ - template, das emuliert Haskell ist teilweise Anrufe Schließungen, d.h. die automatische Erstellung einer Schließung der
m-n
argumments, wenn Sie anrufen, mitn
argumments eine Funktion mitm
Parameter.Dies ist ein Beispiel dafür, was dieses experiment ist cappable zu tun:
haskell::make_function
verwendet einige geben, die Züge kümmern sich um die verschiedenen Arten von Funktion Entitäten, Lambda-Ausdrücke enthalten:Wie Sie sehen können, ich benutze Komma-operator zu mmimic Haskell-syntax, aber Sie ändern könnte, um den Anruf Betreiber Ihr Ziel zu erreichen syntax.
Ihr völlig frei, zu tun, was Sie wollen, mit dem code (Prüfung der Lizenz).
InformationsquelleAutor Manu343726
In C++17 es ist der Konstruktor Typ Abzug. Sie sparen sich damit einiges an schreibarbeit für die std::function-template-Argumente. Das ist nicht ganz nichts, aber ein bisschen weniger.
InformationsquelleAutor user2281723