Utiliser lambda comme argument: std :: function ou template?

J’étudie c ++ 11 particulièrement intéressé par lambda.

Après quelques pratiques, j’ai supposé que la fermeture de lambda était un object fonction sans nom.

Alors j’ai écrit ce code.

template  void lambda_caller( callable_object lambda ) { std::cout<< sizeof(lambda) << endl; lambda(); } 

Je sais que je peux utiliser std::function au lieu d’utiliser template, mais je ne veux pas de surcharge lors de la conversion.

Mais j’ai trouvé un problème en lisant cette question: pourquoi ne puis-je pas créer un vecteur de lambda en C ++ 11?

Le répondant a déclaré: “Chaque lambda a un type différent, même s’ils ont la même signature.”.

Les compilateurs créent différents codes pour différentes classes.

Je pense donc que mon compilateur créera une autre version de lambda_caller chaque fois que je lambda_caller une autre définition de lambda.

Y a-t-il un moyen de l’éviter, si ce n’est d’utiliser std::function ? N’y a-t-il pas de type générique pour la fermeture lambda?

Vous ne pouvez pas l’éviter. Lambda est juste une classe avec operator () () surchargée qui exécute votre code. Code si différent – différentes classes.

std::function est le type générique des fermetures lambda. Le problème est que chaque lambda peut capturer différentes variables. Donc, il ne peut pas être réduit à dire un pointeur de fonction et quelques données, car le lambda peut avoir capturé 3 variables ou 4. 4. std::function veillera à ce que suffisamment de mémoire soit allouée pour les données, mais cela a un coût (les données peuvent être allouées en tas).

Cependant, si vous voulez stocker plusieurs lambdas, et vous savez combien au moment de la compilation. Vous pouvez les stocker dans un std::tuple place. Ce qui autorise différents types pour chaque lambda. Malheureusement, C ++ ne fournit toujours pas un moyen de parcourir un tuple, mais vous pouvez utiliser Boost.Fusion .