Je me demande s'il est possible d'écrire une fonction qui renvoie une fonction lambda en C ++ 11. Bien sûr, un problème est de savoir comment déclarer une telle fonction. Chaque lambda a un type, mais ce type n'est pas exprimable en C ++. Je ne pense pas que cela fonctionnerait:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
Ni ceci:
int(int) retFun();
Je ne suis pas au courant de conversions automatiques de lambdas en, par exemple, des pointeurs vers des fonctions, ou quelque chose du genre. La seule solution est-elle de fabriquer à la main un objet de fonction et de le renvoyer?
decltype
n'est pas le même que dans le corps de la fonction et a donc un type différent (même si vous avez inclus l'instruction de retour)decltype([](){})
ousizeof([]() {})
est mal formé, peu importe où vous l'écrivez.Réponses:
Vous n'avez pas besoin d'un objet de fonction fabriqué à la main, utilisez simplement
std::function
, vers lequel les fonctions lambda sont convertibles:Cet exemple renvoie la fonction d'identité entière:
la source
std::function
.std::function
effacement de type est utilisé, ce qui peut entraîner le coût d'un appel de fonction virtuelle lors de l'appel destd::function
. Quelque chose à savoir si la fonction retournée va être utilisée dans une boucle interne serrée ou dans un autre contexte où la légère inefficacité compte.Pour cet exemple simple, vous n'avez pas besoin de
std::function
.À partir du §5.1.2 / 6 standard:
Étant donné que votre fonction n'a pas de capture, cela signifie que le lambda peut être converti en un pointeur vers une fonction de type
int (*)(int)
:C'est ce que je comprends, corrigez-moi si je me trompe.
la source
Vous pouvez renvoyer une fonction lambda à partir d'une autre fonction lambda, car vous ne devez pas spécifier explicitement le type de retour de la fonction lambda. Écrivez simplement quelque chose comme ça dans une portée globale:
la source
Bien que la question porte spécifiquement sur C ++ 11, pour le bien des autres qui trébuchent sur cela et ont accès à un compilateur C ++ 14, C ++ 14 permet maintenant des types de retour déduits pour les fonctions ordinaires. Ainsi, l'exemple de la question peut être ajusté juste pour fonctionner comme vous le souhaitez en supprimant simplement la
-> decltype
clause ... après la liste des paramètres de la fonction:Notez, cependant, que cela ne fonctionnera pas si plus d'un
return <lambda>;
apparaît dans la fonction. En effet, une restriction sur la déduction du type de retour est que toutes les instructions de retour doivent renvoyer des expressions du même type, mais chaque objet lambda reçoit son propre type unique par le compilateur, de sorte que lesreturn <lambda>;
expressions auront chacune un type différent.la source
auto retFun() { return [](auto const& x) { return x; }; }
Vous devriez écrire comme ceci:
pour obtenir votre retour en tant que fonction, et utilisez-le comme:
la source
Si vous n'avez pas c ++ 11 et exécutez votre code C ++ sur des micro-contrôleurs par exemple. Vous pouvez renvoyer un pointeur vide, puis effectuer une distribution.
la source