Crunchez vos adresses URL
|
Rejoignez notre discord
|
Hébergez vos photos
Page 79 sur 182 PremièrePremière ... 2969717273747576777879808182838485868789129179 ... DernièreDernière
Affichage des résultats 2 341 à 2 370 sur 5456
  1. #2341
    Il me semble que c'est turing complet (accidentellement d'après la légende), même avant les templates variadiques. Mais quand on fait des trucs complexes ça peut devenir très moches. C'est mieux quand ces horreurs sont cachées dans la bibliothèque standard (ou une autre bibliothèque).

  2. #2342
    Citation Envoyé par vectra Voir le message
    On dirait que les mecs ont implémenté un système fonctionnel complet pour la métaprogrammation, genre un lisp en compile-time
    Un Lisp tout court, quoi ^^
    Avec une grammaire horrible.

    https://rosettacode.org/wiki/Compile...on#Common_Lisp
    Sleeping all day, sitting up all night
    Poncing fags that's all right
    We're on the dole and we're proud of it
    We're ready for 5 More Years

  3. #2343
    defmacro, c'était pas si souple que cela, même si plus que les templates. Mais tu pouvais utiliser le même langage pour générer le code que celui du programme. Mais tu pouvais pas spécialiser une fonction selon le type d'appel sans sortir de la norme...

    Par contre, je cherche toujours l'équivalent du macroexpand en c++, ce que cpp n'est pas apparemment.
    J'ai au moins trouvé la macro magique qui permet de tracer les appels de fonctions templates avec les types d'appels, ça aide un peu avec le variadisme...

  4. #2344
    Non mais pas besoin de defmacro, justement, enfin si mais pour les cas de métaprogrammation très meta. Là tu peux utiliser define-compiler-macro.
    Mais bon, en vrai les gens se pignolent beaucoup sur de l'exécution code à la compilation, mais c'est rarement très très utile en pratique par rapport à exécuter le code au loading, ou générer les constantes par un run d'un autre programme.
    Ceci dit, le fait de hasher des const strings à la compile en faisant disparaître les chaines de l'exécutable a longtemps été une arlésienne
    Sleeping all day, sitting up all night
    Poncing fags that's all right
    We're on the dole and we're proud of it
    We're ready for 5 More Years

  5. #2345
    Des livres sur l'intelligence artificielle et le Deep Learning:
    https://www.humblebundle.com/books/a...learning-books
    "Déconstruire", c'est "détruire" en insérant des "cons".
    Battle.net (Diablo 3) : Fbzn#2658 ----- / ----- / ----- Steam ID

  6. #2346
    Citation Envoyé par Cwningen Voir le message
    Idée rapide non testée : utilise un type spécial pour les arguments à convertir.

    Code:
    template<typename Input>
    struct convert_to_voxel_type {
        Input input;
    };
    template<typename T> convert_to_voxel_type(T) -> convert_to_voxel_type<T>;
    
    // cas général, ne change rien au paramètre
    template<typename Voxel, typename T>
    T convert_arg (T value) {
        return value;
    }
    
    // surcharge pour les cas à convertir
    template<typename Voxel, typename T>
    Voxel convert_arg (convert_to_voxel_type<T> value) {
        return boost::lexical_cast<Voxel>(value.input);
    }
    Pour convertir les arguments dans execute_dispatch, par exemple dans le cas double, "convert_arg<double>(arg)...", et pour l'appeler, tu passes des "convert_to_voxel_type{"-32768"}".
    Bon, j'ai repris le truc en question avec un peu de distance et de repos.
    J'ai viré SITK et autres du code en question histoire d'avoir quelque chose qui compile tout seul. Comme ça, ça compile même en ligne
    La preuve:

    https://ideone.com/cBE6Df

    J'ai mieux séparé les choses ici. L'usage des templates variadiques semble me convenir pour ce que j'ai à faire, et je n'ai pas eu besoin du forward pour cet exemple (j'ai assez bien compris move/lvalue/rvalue, mais forward m'est un peu obscur encore).
    Une chose que j'aurais bien aimé faire, c'est virer le plus de choses possibles de la classe CustomDispatcher (que l'utilisateur devra créer pour chaque filtre utilisateur) et en mettre le plus possible dans DispatcherMother.
    J'ai notamment bien étudié le CRTP, mais il semble bien que les templates le mettent à l'amende (ou bien ma connaissance de la syntaxe - mais ça c'est pas dûr ).
    A défaut de le refiler à la mère par le CRTP, j'ai déjà réussi à masquer l'opérateur() dans la fille en le remplaçant avec succès par un appel de macro, mais c'est trop sale et j'aurais bien aimé comprendre un mécanisme qui résolve cela élégamment

  7. #2347
    Citation Envoyé par vectra Voir le message
    L'usage des templates variadiques semble me convenir pour ce que j'ai à faire, et je n'ai pas eu besoin du forward pour cet exemple (j'ai assez bien compris move/lvalue/rvalue, mais forward m'est un peu obscur encore).
    forward c'est un move conditionnel en fonction du type passé en paramètre de template. Si tu passe une référence de lvalue, il ne fait rien, si tu passes un type de valeur, c'est équivalent à un move. C'est surtout dans la déduction de type des templates que se cache la complexité. Si, dans un template de paramètre T, tu vois "T &&", ce n'est pas une référence de rvalue, on appelle ça une référence universelle ou "forwarding reference". Si tu passes une lvalue, T est déduit en "type &" ou "const type &" et "T &&" est en fait une référence de lvalue. Si tu passes une rvalue, T est simplement le type sans rien ajouté et "T &&" est une référence de rvalue. On s'en sert surtout quand on veut accepter n'importe quel type de paramètre pour les passer tel quel et sans copies à une autre fonction (grâce à forward), ce qu'on appelle "perfect forwarding". Je sais pas si j'ai été clair mais tu as les mot-clés pour chercher des explications par des gens plus compétents.

    Dans ton cas, si tu n'as que des types primitifs (int, double, float, ...), ce n'est pas très important, mais ça le devient quand tu veux passer des objets plus complexes qui pourraient profiter d'un move. Je n'ai pas trop réfléchi en écrivant mon exemple et j'ai du en abuser, beaucoup sont sûrement inutiles.

    Citation Envoyé par vectra Voir le message
    J'ai notamment bien étudié le CRTP, mais il semble bien que les templates le mettent à l'amende (ou bien ma connaissance de la syntaxe - mais ça c'est pas dûr ).
    A défaut de le refiler à la mère par le CRTP, j'ai déjà réussi à masquer l'opérateur() dans la fille en le remplaçant avec succès par un appel de macro, mais c'est trop sale et j'aurais bien aimé comprendre un mécanisme qui résolve cela élégamment
    Je comprends pas trop ce qui te pose problème. Ton exemple semble fonctionner quand je supprime la fonction de CustomDispatcher et décommente celle de ExecutorMother.

  8. #2348
    Citation Envoyé par Cwningen Voir le message
    Je comprends pas trop ce qui te pose problème. Ton exemple semble fonctionner quand je supprime la fonction de CustomDispatcher et décommente celle de ExecutorMother.
    Mais purée oui
    J'ai fait boulette avec mon projet alors ?? Réponse demain

  9. #2349
    Citation Envoyé par Cwningen Voir le message

    Je comprends pas trop ce qui te pose problème. Ton exemple semble fonctionner quand je supprime la fonction de CustomDispatcher et décommente celle de ExecutorMother.
    Désolé, j'étais trop fatigué hier soir pour comprendre ce qui se passait.

    Voici un lien sur la version dont tu parles, nettement mieux commentée. Elle compile, mais ne fonctionne pas comme attendu ( fonction filtre int appellée quand double requise ; les sorties ont été corrigées pour que ça soit visible ).
    En effet, pour compiler la version CRTP, j'ai dû enlever les paramètres template à l'appel des fonctions filtre. Du coup, il sélectionne toujours la version int du filtre, peu importe le type de données sur lequel il travaille. Et donc, il échoue pour l'appel sur des données double.

    https://ideone.com/WGiGPa

    Je voudrais savoir quel élément syntaxique il me manque pour que ça compile, en fait.

  10. #2350
    Le problème est que quand le compilateur lit la fonction (avant de l'instancier), il ne sait pas que filter_function est un template et donc ne sait pas interpréter les < >. Ajoute un mot-clé template pour préciser : "derived . template filter_function<double>(arguments ...);"

  11. #2351
    Ca
    Marche


    Il me manquait bien un élément de syntaxe alors...
    Je n'avais encore jamais mis un 'template' dans un endroit pareil.

    Il va falloir que j'étudie la métaprogrammation d'un peu plus près quand-même

    Ce qui m'amène à une autre question sur des bouquins qu'ils sont bien pour le C++14/17...
    Avec des morceaux de templates dedans...

  12. #2352
    Citation Envoyé par vectra Voir le message
    Il va falloir que j'étudie la métaprogrammation d'un peu plus près quand-même
    Citation Envoyé par Sidus Preclarum Voir le message
    Ben du caramel pas sucré alors...
    "Avant, j'étais dyslexique, masi aujorudh'ui je vasi meiux."

  13. #2353
    Vrai bouquin aperçu:



    Blague à part, j'ai pris celui-là à 13 euros.

    Il date peut-être légèrement un peu (2004), mais ça ne peut faire de mal à ce prix. Je reste open à des suggestions de livres récents, mais si possible pas auto-édités
    Dernière modification par vectra ; 17/05/2019 à 17h19.

  14. #2354
    Tu veux une copie de ma thèse ?

    Comme ça tu me fera un résumé j'ai du mal à me rappeler ce qu'il y a dedans.
    Citation Envoyé par Sidus Preclarum Voir le message
    Ben du caramel pas sucré alors...
    "Avant, j'étais dyslexique, masi aujorudh'ui je vasi meiux."

  15. #2355
    Trop que oui.
    Ca poursuivra ma collèque de thèse des canards de ce forum


    Tiens, j'ai trouvé un tutorial assez bien fait sur les templates:
    https://monoinfinito.wordpress.com/s...taprogramming/
    Dernière modification par vectra ; 17/05/2019 à 19h42.

  16. #2356
    Merci Lazy! Et merci encore Cwningen

    Par contre, j'ai encore une question par rapport au code de vendredi.

    Alors je l'ai adapté sur SITK, et ça fait exactement purée de ce que je voulais
    Mais ce que je ne comprends pas, c'est pourquoi, dans ma fonction filtre template, ImageType me renvoie toujours le type de données pour lequel l'image a été instanciée. C'est pile ce que je voulais, mais je ne comprends pas la règle qui me donne cela.

    Voici le code en version lib générique:
    https://ideone.com/QS0dSa

  17. #2357
    ImgDataType ? Tu le passes explicitement en paramètre du template quand tu appelles la fonction, donc il n'y a pas d’ambiguïté dans le choix de la version à appeler. Tu passes un int à ExecutorMother dans l'exemple, donc c'est convertible implicitement en double ou float. Avec d'autres types ça ne passerait pas (comme les chaines que tu utilisais initialement).

  18. #2358
    Mais oui
    J'oublie ce que j'ai écrit.
    C'est juste que ça fonctionne trop comme je le souhaitais, et ça me perturbe qu'une implémentation aussi simple ne résolve tout aussi vite.

  19. #2359
    J'aurais une question d'ordre généraliste sur le CRTP.
    En continuant à chercher J'ai vu ça trainer sur fluentcpp (j'ai juste joué un peu avec):

    Version complète et plus lisible en: https://ideone.com/xsCxpI

    Le paquet des classes qui étendent la classe de base:

    // 1st extension class
    template <typename T>
    struct NumericalFunctionsScale
    {
    T& underlying = static_cast<T&>(*this); // convenience

    void scale(double multiplicator)
    {
    underlying.setValue(underlying.getValue() * multiplicator);
    }
    };

    // 2nd extension class
    template <typename T>
    struct NumericalFunctionsOther
    {
    T& underlying = static_cast<T&>(*this);

    void square()
    {
    underlying.setValue(underlying.getValue() * underlying.getValue());
    }
    void setToOpposite()
    {
    underlying.scale(-1);
    };
    };
    La classe de base dans sa plus simple expression:

    // Here, the base class we want to extend by additionnal 'packages'
    class Sensitivity : public NumericalFunctionsScale<Sensitivity>, public NumericalFunctionsOther<Sensitivity>
    {
    public:
    Sensitivity():Sensitivity(0) {}
    Sensitivity(double d):value_{d} {}

    double getValue() const { return value_ ; }
    void setValue(double value) { value_ = value; }
    ostream& print(ostream& o) { o << endl << value_; return o; }

    protected:
    double value_;
    };
    On peut directement utiliser une instance de la classe avec toutes ses extensions par défaut.
    Avec l'héritage au lieu du CRTP, on aurait cette classe comme classe de base, les 'packages' qui en dérivent, et instancier la dernière classe dérivée.

    int main(void)
    {
    Sensitivity s(3.14);
    s.scale(2.0);
    s.print(cout);
    return 0;
    }
    En gros, on peut utiliser (dévoyer?) le CRTP pour casser une classe entre une base et plusieurs packages additionnels, mais qui finissent tous "mergés" dans la classe de base.

    C'est quelque chose que je cherchais à pouvoir faire depuis un moment, à savoir découper une grosse classe riche en fonctionnalités en plusieurs blocs modulaires, sans qu'il y ait vraiment de sens à utiliser l'héritage pour cela (is-a, has-a). Je voudrais plutôt completes, ce qui semble correspondre au principe du Mixin)
    Il y a moyen de faire cela avec l'héritage, mais ça me semblait tellement pénible que j'ai jamais pu l'appliquer.
    A défaut, je finissais par des #include de fichiers séparés

    Qu'est-ce que cela vous inspire?
    C'est pas un truc que je vais appliquer tout de suite, plutôt une réflexion à long terme sur comment rendre mes codes plus lisibles.

    Source: https://www.fluentcpp.com/2017/05/19/crtp-helper/
    Dernière modification par vectra ; 21/05/2019 à 18h01. Motif: pleins de modifs et addenda, désolé

  20. #2360
    C'est pas hyper lisible à mon avis. Après ça peut être pas mal pour injecter des trucs transverses dans des classes sans avoir à dupliquer le code ou en économisant des indirections.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  21. #2361
    Je trouve ça pas mal

  22. #2362
    Tiens, ça fait longtemps que je voulais trouver quelque chose de plus facile à utiliser que boost:rogram_options. Je l'aime bien, mais c'est bien trop verbeux.
    Je me demandais si ça valait le coup de simplifier par métaprogrammation les codes que j'utilisais, mais visiblement y'a quelqu'un qui l'a fait pour moi

    https://github.com/matt-42/iod/blob/...ommand_line.cc

    Code:
       const char* argv[] = {"", "--opt1", "0", "-abc", "-d=0"};
        auto opts = parse_command_line(4, argv,
                                       _opt1 = bool(),
                                       _a = bool(),
                                       _b = bool(),
                                       _c = bool(),
                                       _d = bool());
    
        assert(opts.opt1 == false and
               opts.a == true and
               opts.b == true and
               opts.c == true and
               opts.d == false);

  23. #2363
    Quelques ouvrages de programmation en bundle:
    https://www.humblebundle.com/books/p...ng-packt-books
    "Déconstruire", c'est "détruire" en insérant des "cons".
    Battle.net (Diablo 3) : Fbzn#2658 ----- / ----- / ----- Steam ID

  24. #2364
    Question pour les canards, je corrige un contrôle là, et un élève m'a mis le doute :
    J'ai un appel récursif comme ceci en C.
    Code:
    int toto(int a, int n)
    {
      if (n>0)
      {
        a=a*n;
        n=n-1;
        return toto(a,n);
      }
      else
      {
        return a;
      }
    }
    La question porte sur le fait de donner un exemple d'algo récursif non terminal et l’élève donne donc cet exemple.

    Mais il m'a mis un doute, la terminalité, je rappelle, c'est quand la dernière instruction est un return sur sa propre fonction sans opération supplémentaire (pas de return 1+toto par exemple) . Et là j'ai un petit doute parce que le else ... est-il véritablement "évalué" après le return ?
    J'aurais dit qu'en théorie il n'est pas du tout évalué car dés qu'on rentre dans le if le else est caduque et donc que return toto est bien la dernière instruction évalué de l'algo ...ce qui en fait un algo récursif terminal (donc l’élève aurait faux)

    Mais ai-je tort ?

    J'avoue que j'ai un trou sur le sujet, je ne me souvient plus comment est évalué exactement le else dans le cas du if/else sans else if.
    Dernière modification par Nilsou ; 26/06/2019 à 03h10.

  25. #2365
    Pour moi c'est terminal, il retourne bien directement le retour de l'appel récursif. L'ordre des clauses n'a pas d'importance. Un return est toujours la "dernière instruction" (c'est le principe du return).

    L'exemple est même trop parfait pour un algorithme récursif terminal (il n'y qu'à remplacer le if par un while et enlever l'appel terminal pour avoir la version itérative), on dirait une mauvaise lecture d'énoncé.

  26. #2366
    Nan mais le but c'était de donner des exemples types. Que ce soit facilement déroulable ou non n'avait que peu d'importance dans notre cas.

    Donc c'est bien terminal, je ne me suis pas foiré Merchi

  27. #2367
    yep terminal.

  28. #2368
    Moi je fais du C maintenant, je prends beaucoup de plaisir.

    Code:
    void (*glXGetProcAddressARB(const char *procName))(void) {
    
      /* ... */
    
      return ((_GLX_PUBLIC void (*(*)(const GLubyte *))(void))next)(procName);
    }
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  29. #2369

  30. #2370
    Non non, tout va bien, la preuve : https://gcc.godbolt.org/z/WOcAT2
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

Page 79 sur 182 PremièrePremière ... 2969717273747576777879808182838485868789129179 ... DernièreDernière

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •