2010-07-01 13 views
9

J'ai lu quelque part qu'une fonction lambda devrait se désintégrer au pointeur de fonction si la liste de capture est vide. La seule référence que je peux trouver maintenant est n3052. Avec g ++ (4.5 & 4.6) cela fonctionne comme prévu, à moins que le lambda ne soit déclaré dans le code du template.Est-ce que lambda doit se désintégrer en pointeur de fonction dans le code modélisé?

Par exemple le code suivant compile:

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

Mais il ne compile pas plus quand templated (si foo est effectivement appelé ailleurs):

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

Dans la référence ci-dessus, je ne Ne vois pas une explication de ce comportement. Est-ce une limitation temporaire de g ++, et sinon, y a-t-il une raison (technique) de ne pas le permettre?

+1

Notez que N3052, que vous citez, a bien été incorporé dans le FCD C++ 0x (N3092 5.1.2/6). Visual C++ 2010 n'implémente pas du tout la conversion (sans surprise, puisque le langage permettant de l'incorporer dans la norme si tôt avant la sortie de VC++). J'ai soumis un rapport de bogue sur Microsoft Connect à ce sujet (bien que je prévois qu'il ne sera pas corrigé jusqu'à la prochaine version de Visual C++): https://connect.microsoft.com/VisualStudio/feedback/details/572138/visual -c-2010-does-not-allow-conversion-of-captureless-lambda-to-function-pointer –

+0

Juste comme un FYI: Aucun du code ci-dessus n'est supporté dans Intel C++ 11.1 –

+1

Son déjà dans GCCs bugtracker, bien que de maintenant non confirmée: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45080 –

Répondre

3

Je ne peux penser à aucune raison que ce soit spécifiquement refusé. Je suppose que c'est juste une limitation temporaire de g ++.

J'ai essayé aussi quelques autres:

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

foo<int>([]{}); 

qui fonctionne.

typedef void (*fun)(void); 

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

foo<int>()(); 

Cela ne veut pas (mais ne se foo est pas paramétrés).

Note: J'ai seulement testé en g ++ 4.5.

+0

Oui, dans le premier cas, le lambda est déclaré dans une partie non-modèle de code (bien qu'il soit utilisé par une fonction de modèle) . Le même problème se produit lorsque le lambda est déclaré dans une classe de modèle. – rafak