2010-06-07 4 views
28

Ich versuche, einen Lambda-Ausdruck an eine Funktion übergeben, die einen Funktionszeiger nimmt, ist das überhaupt möglich? HierKann ein Lambda-Ausdruck als Funktionszeiger übergeben werden?

ist ein Beispielcode, ich bin mit VS2010:

#include <iostream> 
using namespace std; 

void func(int i){cout << "I'V BEEN CALLED: " << i <<endl;} 

void fptrfunc(void (*fptr)(int i), int j){fptr(j);} 

int main(){ 
    fptrfunc(func,10); //this is ok 
    fptrfunc([](int i){cout << "LAMBDA CALL " << i << endl; }, 20); //DOES NOT COMPILE 
    return 0; 
} 
+0

Compiliert und läuft mit gcc-4.5.1 unter Linux (aber kompiliert nicht in 4.4.3, das keine lambdas hat) – Cubbi

Antwort

26

In VC10 RTM, nein - aber nach der Lambda-Funktion in VC10 fertig gestellt wurde, der Standard-Ausschuß Sprache nicht hinzugefügt, die staatenlos lambdas erlaubt degrade zu Funktionszeigern. Dies wird in Zukunft möglich sein.

+0

Erinnerst du dich an welchen Abschnitt das war? Das ist interessant. – rlbond

+3

@rlbond: N3090/3092, §5.1.2/6 –

+0

Mit Stateless Lambda, meinen Sie ein Lambda, das keine lokalen Variablen entweder nach Wert oder durch Referenz nimmt? – balki

0

Nein. Es kann nicht. Zumindest nicht zuverlässig. Ich weiß, dass VS2010 sie als Objektfunktoren implementiert. Basierend auf, wie sie arbeiten, die eine a priori Anforderung sein kann.

13

Sie können std::function für diesen Einsatz:

void fptrfunc(std::function<void (int)> fun, int j) 
{ 
    fun(j); 
} 

Oder gehen vollständig generisch:

template <typename Fun> 
void fptrfunc(Fun fun, int j) 
{ 
    fun(j); 
} 
4

Dies funktioniert in VS2010:

template<class FunctorT> 
void* getcodeptr(const FunctorT& f) { 
    auto ptr = &FunctorT::operator(); 
    return *(void**)&ptr; 
} 

void main() { 
    auto hello = [](char* name){ printf("hello %s\n", name); }; 
    void(*pfn)(char*) = (void(*)(char*)) getcodeptr(hello); 
    pfn("world"); 
} 
+0

das scheint nicht zu funktionieren ... der Ausgang, den ich bekomme, ist Hallo _ – subzero

0

Solange die Lambda nicht Verwenden Sie Capture-Klausel (dh nicht von oben Variablen erfassen), kann es als Funktionszeiger verwendet werden. Der VC-Compiler generiert intern anonyme Funktionen mit unterschiedlichen Aufrufkonventionen, so dass er ohne Probleme verwendet werden kann.

Verwandte Themen