lambda als Funktionsparameter
-
Ich habe folgenden code:
#include <iostream> #include <functional> using namespace std; template<typename R, typename A> void createAccessor(R(*acc)(A)) { std::function<R(A)> func = acc; } int main() { createAccessor([](int arg){ return 42; }); return 0; }
prog.cpp: In function ‘int main()’:
prog.cpp:12:42: error: no matching function for call to ‘createAccessor(main()::__lambda0)’
createAccessor([](int arg){ return 42; });Wieso kann ich nicht das lambda als Funktionsparameter übergeben?
-
Weil ein Lambda kein Funktionszeiger ist. Er lässt sich lediglich in einen Konvertieren (da hier keine captures vorhanden sind), aber das hat keinen Einfluss auf die Deduzierung der Template-Argumente.
Das hier kompiliert
void createAccessor( int(*acc)(int) ) { std::function<int(int)> func = acc; } createAccessor([](int arg){ return 42; });
Was du natürlich tun könntest ist vor dem Aufruf explizit casten.
-
Die vollständige Meldung beim g++ 4.8.1 lautet:
lambda.cpp: In function ‘int main()’:
lambda.cpp:12:45: error: no matching function for call to ‘createAccessor(main()::__lambda0)’
createAccessor([](int arg){ return 42; });
^
lambda.cpp:12:45: note: candidate is:
lambda.cpp:6:6: note: template<class R, class A> void createAccessor(R (*)(A))
void createAccessor(R(acc)(A))
^
lambda.cpp:6:6: note: template argument deduction/substitution failed:
lambda.cpp:12:45: note: mismatched types ‘R ()(A)’ and ‘main()::__lambda0’
createAccessor([](int arg){ return 42; });Da der Lambdaausdruck kein Funktionspointer ist, sondern nur in einen konvertiert werden kann, geht es nicht automatisch. So gehts:
#include <iostream> #include <functional> using namespace std; template<typename R, typename A> void createAccessor(R(*acc)(A)) { std::function<R(A)> func = acc; } int main() { int(*acc)(int) = [](int arg){ return 42; }; createAccessor(acc); return 0; }
Oder du benutzt gleich std::function als Parameter.
-
Oder du benutzt gleich std::function als Parameter.
Dann stellt sich allerdings die Frage, warum nicht gleich einfachtemplate<typename T> void foo( T bar ) { // ... bar(arg) }
-
manni66 schrieb:
Oder du benutzt gleich std::function als Parameter.
Dann funktioniert die Typherleitung aber auch nicht.
-
TyRoXx schrieb:
manni66 schrieb:
Oder du benutzt gleich std::function als Parameter.
Dann funktioniert die Typherleitung aber auch nicht.
Ohne Witz, meine erste Version des Postings oben war "Was ändert das?".
Ich hasse Denkfehler, ich hasse sie so sehr
-
manni66 schrieb:
Oder du benutzt gleich std::function als Parameter.
Das bringt doch aber nichts, da kann ich trotzdem nicht
createAccessor([](int arg){ return 42; });
aufrufen.
Oder was meinst du?Was ich machen könnte ist folgendes:
#include <iostream> #include <functional> using namespace std; template<typename R, typename A> void createAccessor(R(*acc)(A)) { std::function<R(A)> func = acc; } int main() { createAccessor<int,int>([](int arg){ return 42; }); return 0; }