2010-07-01 8 views
9

Ich habe irgendwo gelesen, dass eine Lambda-Funktion zum Funktionszeiger abfallen sollte, wenn die Aufnahmeliste leer ist. Die einzige Referenz, die ich jetzt finden kann, ist n3052. Mit g ++ (4.5 & 4.6) funktioniert es wie erwartet, es sei denn, das Lambda wird im Template-Code deklariert.Sollte Lambda in einem templateten Code zu einem Funktionszeiger werden?

Zum Beispiel der folgende Code kompiliert:

void foo() { 
    void (*f)(void) = []{}; 
} 

Aber es mehr nicht kompilieren, wenn Templat (wenn foo tatsächlich an anderer Stelle genannt wird):

template<class T> 
void foo() { 
    void (*f)(void) = []{}; 
} 

Im Referenz oben, ich don Ich sehe keine Erklärung für dieses Verhalten. Ist das eine vorübergehende Einschränkung von g ++, und wenn nicht, gibt es einen (technischen) Grund, dies nicht zuzulassen?

+1

Beachten Sie, dass N3052, das Sie anführen, tatsächlich in den C++ 0x FCD (N3092 5.1.2/6) eingebaut wurde. Visual C++ 2010 implementiert die Konvertierung überhaupt nicht (nicht überraschend, da die Sprache so kurz vor Veröffentlichung von VC++ in den Standard aufgenommen wurde). Ich habe diesbezüglich einen Fehlerbericht zu Microsoft Connect gesendet (obwohl ich davon ausgehe, dass dieser Fehler erst mit der nächsten Version von Visual C++ behoben wird): https://connect.microsoft.com/VisualStudio/feedback/details/572138/visual -c-2010-does-not-permission-Umwandlung von-captureless-Lambda-to-Function-Zeiger –

+0

Nur als FYI: Keine der oben genannten Code wird in Intel C++ 11.1 unterstützt –

+1

Es ist bereits in GCCs Bugtracker, obwohl als von jetzt unbestätigt: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45080 –

Antwort

3

Ich kann keinen Grund denken, dass es speziell nicht erlaubt wäre. Ich vermute, dass es nur eine vorübergehende Einschränkung von g ++ ist.

Ich habe auch versucht ein paar andere Dinge:

template <class T> 
void foo(void (*f)(void)) {} 

foo<int>([]{}); 

, das funktioniert.

typedef void (*fun)(void); 

template <class T> 
fun foo() { return []{}; } // error: Cannot convert. 

foo<int>()(); 

das nicht (aber tut, wenn foo nicht parametriert).

Hinweis: Ich habe nur in g ++ 4.5 getestet.

+0

Ja, im ersten Fall wird das Lambda in einem Nicht-Template-Teil des Codes deklariert (obwohl es von einer Template-Funktion verwendet wird) . Dasselbe Problem tritt auf, wenn das Lambda in einer Vorlagenklasse deklariert wird. – rafak

Verwandte Themen