Lambda-Ausdruck als Funktionspointer für Argument [gelöst]
-
Hallo,
ich versuche ein bisschen mit Lambda-Ausdrücken zu spielen, weil ich gesehen habe, dass Visual Studio 2010 (bzw. der Compiler) diese schon unterstützt. Nun habe ich Probleme den Gebrauch zu verstehen.
Ich würde gerne eine Funktion schreiben, die als Paramater einen solchen Lambda-Ausdruck nimmt und den dann dynamisch aufruft mit seinen Parametern. Das Problem ist jedoch, dass ich nicht weiß (ob?) wie es möglich ist einen "Funktionszeiger" auf einen direkt angegebenen Lambda-Ausdruck als Parameter für eine Funktion bereitzustellen.Für jegliche Hilfe bin ich froh
-
Hier mal ein einfaches Bsp:
#include <vector> #include <string> #include <algorithm> #include <iostream> int main() { std::vector<std::string> names; names.push_back("Bruce Willis"); names.push_back("Sylvester Stallone"); names.push_back("Sharon Stone"); // Finde den ersten Namen in dem "Sylvester" vorkommt. std::vector<std::string>::const_iterator it = std::find_if(names.begin(), names.end(), [=](const std::string& name) { return name.find("Sylvester") != std::string::npos; }); if (it != names.end()) { std::cout << *it << std::endl; } }
Edit
Dich interessiert wohl eher wie z.B. std::find_if(..) funktioniert. Ganz einfach, es nimmt ein template Argument (Predicate). Dort kannst Du dann auch ein Lambda Ausdruck übergeben.
-
Grundsätzlich kannst du den "direkten" Typen für Lambda-Funktionen nicht hinschreiben. Entweder man benutzt Typinferenz (
auto
), oder hat bei Funktionen einen Template-Parameter, der beliebige Funktionsobjekte aufnimmt, oder verwendetstd::function
als Behälter.
-
Ich habe mir die Implementierung von
find_if
angesehen, aber das ist alles unheimlich komplex. Könnt ihr mir nicht ein kurzes Beispiel zeigen, wie ich genau das mit dem Template dann umsetze? Zudem habe ich mirstd::function
angesehen, aber das ist auch wirrtemplate<class InputIterator, class Predicate> InputIterator find_if(InputIterator first, InputIterator last, Predicate pred);
-
Was ist dir denn an diesem Code unklar?
pred
ist einfach irgendein Funktionsobjekt oder eine Funktion.Predicate
ist dessen Typ.template<class InputIterator, class Predicate> InputIterator find_if(InputIterator first, InputIterator last, Predicate pred);
-
Ganz einfaches Beispiel:
#include <iostream> template <class Fun> void apply(int i, Fun f) { f(i); } int main() { apply(2, [](int i){ std::cout << i; }); }
Ist natürlich ein absolut sinnfreies Beispiel, aber genauso funktioniert es mit std::generate, std::for_each, etc.
-
Ich bin davon ausgegangen, dass man noch etwas genaues als Templateparameter angeben muss, wenn man die Funktion aufrufen will, aber es klappt schon so
Für dieses Mal wäre das alles denke ich
-
Christian Ivicevic schrieb:
Ich bin davon ausgegangen, dass man noch etwas genaues als Templateparameter angeben muss, wenn man die Funktion aufrufen will, aber es klappt schon so
Für dieses Mal wäre das alles denke ichWichtig zu verstehen ist, dass ein Lambda-Ausdruck zwei Dinge tut: Es definiert einen einzigartigen Klassen-Typ, der keinen Namen hat und es erzeugt ein Objekt dieses Typs.
-
Ich kenne Lambda bisher aus C#, wo man mit LINQ sehr einfach komplexe Zusammenhänge verknüfen kann bzw. genau solche Predicates für beispielsweise Count-Funktionen definieren kann.
Was ich noch versuche, aber nicht ganz schaffe, ist die Einordnung, der übergebenen Ausdrücke in eine map. Ist dies auch möglich? Habe bei den ersten Versuchen den Compiler abschmieren lassen xD
Visual Studio 2010 schrieb:
1>d:\fpp\fc\options.hpp(36): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1420)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
-
Wie gesagt: Du brauchst irgendwas, in dem du die durch Lambda-Funktionen erzeugten Funktionsobjekte abspeichern kannst. Nimm dafür am besten
std::function
.Übrigens: Deine Fehlermeldung bringt uns ohne Codebezug rein gar nichts.
-
Dies Fehlermeldung sollte nur etwas lustiges zeigen
Ich versuch mal, ein bisschen mitstd::function
herumzuspielen um zu sehen, ob ich die Ausdrücke dann korrekt abspeichern kann.
-
Statt herumzuspielen könntest du auch die Dokumentation auf MSDN lesen :p
-
Zwar würde ich so vielleicht schneller ans Ziel kommen, aber wenn man herumspielt und auf Probleme trifft, dann muss man sich damit plagen und lernt so mehr, wenn man dran bleibt!
Auf jeden Fall habe ich es endlich geschafft und bin dabei den Aufbau meiner Klasse etwas zu verbessern und weiter zu abstrahieren. Danke für die Lektion zu Lambdas