9
votes

C ++ 17 Vecteur de Lambdas générique (polymorphe)

C ++ 14 Introduisez des Lambdas génériques (lors de l'utilisation du mot-clé AUTO dans les signatures de la Lambda).

Y a-t-il un moyen de les stocker dans un vecteur avec C ++ 17?

Je sais À propos de cette question existante, mais cela ne convient pas à mes besoins: Puis-je avoir un STD :: Vector des pointeurs de la fonction de modèle?

Voici un exemple de code illustrant ce que j'aimerais faire. (Veuillez consulter les notes en bas avant de répondre) xxx

notes:

  • Le code de A , b et testtrunner ne peut pas être modifié, seul le code des cas de test
  • Je ne veux pas discuter s'il est bon ou mal de coder des tests comme celui-ci, il s'agit d'un hors-sujet (la terminologie de test est utilisée ici uniquement pour illustrer que je ne peux pas énumérer tous les Lambdas (afin d'utiliser une variante Tapez pour eux ...))

0 commentaires

3 Réponses :


5
votes

Il suive une solution possible (que je ne recommanderais pas, mais vous avez explicitement dit que vous ne voulez pas discuter si c'est bon ou faux, etc.).
Comme demandé, a code>, b code> et testtrunner code> n'a pas été changé (mettre de côté le fait que auto code> n'est pas un Paramètre de fonction valide pour Testrunner code> et je l'ai défini en conséquence).
Si vous pouvez modifier légèrement testtrunner code>, le tout peut être amélioré.
Cela étant dit, voici le code:

auto l1 = [](auto &) { /* ... */ };
auto w1 = Wrapper<decltype(l1)>{std::move(l1)};


4 commentaires

Auto est un paramètre de fonction valide pour TestRunner en C ++ 14 ( ideone.com/4931Ht )


Cette solution polymorphe est très intelligente +1.


@infiniteloop Voir le fonctionnement sur wandbox avec auto . Notez qu'il s'agit d'une extension GCC, pas d'un paramètre valide en C ++ 14 pour des fonctions libres.


Qu'est-ce que le Downvote exactement? O.o ... sachant que cela aiderait à améliorer la réponse ...



0
votes

Fondamentalement ce que vous voulez, c'est une extension de std :: Fonction code>.

std :: fonction code> est une appelable effaçable de type qui peut modeler que Signature particulière. Nous voulons toute cette fonctionnalité, mais avec plus de signatures et que toutes ces signatures soient surchargées. Où cela devient difficile, c'est que nous avons besoin d'une pile linéaire de surcharges. Cette réponse suppose la nouvelle règle C ++ 17 permettant d'élargir les packs de paramètres dans une déclaration à l'aide de la déclaration et de construire des morceaux à partir de la masse. De plus, cette réponse n'est pas concentrée sur l'évitant de toutes les copies / films si nécessaire, je consomme juste l'échafaudage. En outre, il doit y avoir plus de Sfinae. P>


Premièrement, nous avons besoin d'un appel d'appel virtuel pour une signature donnée: p> xxx pré>

et quelque chose pour les regrouper: p> xxx pré>

maintenant la partie ennuyeuse. Nous avons besoin d'un espace réservé code> pour remplacer chacun de ces appel () code> s. Il peut y avoir une meilleure façon de le faire, mais la meilleure façon dont je pouvais penser est d'avoir deux paramètres de modèle de frappe de frappe et de déplacer chaque signature de l'une à l'autre, car nous finissons avec eux: P>

std::vector<function<void(A&), void(B&)>> actions;


0 commentaires

0
votes

Il n'est pas possible de stocker des modèles de fonctions de quelque manière que ce soit, de la forme ou de la forme. Ce ne sont pas des données. (Les fonctions ne sont pas non plus données, mais les pointeurs de fonction sont). Notez qu'il existe STD :: Fonction, mais pas de std :: Function_Template. Il existe des fonctions virtuelles, mais pas de modèles de fonctions virtuels. Il y a des pointeurs de la fonction, mais pas de pointeurs de modèle de fonction. Ce sont toutes des manifestations d'un fait simple: il n'y a pas de modèles au moment de l'exécution.

Un Lambda générique n'est qu'un objet avec un opérateur () code> Modèle de fonction membre. Tout de ce qui précède s'applique également aux modèles membres. p>

Vous pouvez obtenir un ensemble de spécialisations de modèles finis et déterminé par la compilation de compilation pour me comporter comme un objet, mais ce n'est pas différent d'un objet, d'avoir un groupe fini de fonctions virtuelles (éventuellement surchargées). ou peu importe. Dans votre situation, c'est un équivalent d'avoir un P>

std::vector <
    std::tuple <
         std::function<void(A&)>,
         std::function<void(B&)>
    >
 >


0 commentaires