Crunchez vos adresses URL
|
Rejoignez notre discord
|
Hébergez vos photos
Page 91 sur 334 PremièrePremière ... 41818384858687888990919293949596979899101141191 ... DernièreDernière
Affichage des résultats 2 701 à 2 730 sur 10008
  1. #2701
    Tu dois pouvoir faire hériter Volume<T> d'une classe de base non-template avec des fonctions membres virtuelles (traitement, set_file, write) que tu surcharges dans la version template. Ton wrapper n'a plus qu'à appeler le new qui va bien et te renvoyer un pointeur sur l'objet de base, tu ne devrais pas avoir à te trimballer le wrapper... hopefully.

    Après, c'est pas le meilleur use case pour les templates...

  2. #2702
    Y a pas de méthode miracle pour ça. Quand tu compiles ton Volume<int> et quand tu compiles ton Volume<float> ça génère deux codes totalement différents, du coup t'as pas d'autre choix à part soit appeller l'un ou l'autre.

    Si t'as pas envie de faire d'héritage, le plus simple c'est de coder une classe comme ça : (écrit en vitesse)

    Code:
    class Loader {
    public:
        // remplit "storage" et "type"
        void load(const std::string& file);
    
        template<typename T>
        bool isType() const       { return &typeid(T) == &type; }
    
        template<typename T>
        Volume<T> toType()     { assert(isType<T>()); return static_cast<Volume<T>>(*storage); }
        
    
    private:
        std::shared_ptr<void>   storage;   // contient soit un Volume<int>, soit un Volume<float>, etc.
        std::type_info const*    type;      // peut être int, float, double, etc.
    };
    Ensuite à l'extérieur tu fais ça :

    Code:
    Loader l("fichier");
    
    if (l.isType<int>())        Program<int>(l.toType<int>());
    else if (l.isType<float>())    Program<float>(l.toType<float>());
    etc.
    Et du coup tu aurais une classe Program avec un paramètre template.

    EDIT : Cela dit à un moment ou à un autre tu seras obligé d'utiliser un minimum d'héritage, à toi de voir à quel endroit c'est le plus simple.
    Par exemple si t'as juste "class ProgramInterface { virtual void executeCommand(const std::string&) = 0; }" c'est probablement le meilleur endroit.
    Rust fanboy

  3. #2703
    Citation Envoyé par Tomaka17 Voir le message
    Ben t'as le MSAA qui consiste à dessiner sur une grande surface puis à réduire sa taille en faisant un filtrage bilinéaire.

    Sinon t'as des algos de ce genre, mais ça se fait sur des images et ce sont des traitements assez complexes.
    Ca c'est le SSAA, mais c'est gourmand.
    Le MSAA lui est plus performant mais a besoin d'accéder à la géométrie et il ne lisse pas les textures (transparentes ou non).
    Sinon il y a les AA post-process du type FXAA/MLAA/SMAA, mais ils ont pas l'air de donner de bons résultats avec le texte (p'tet la façon dont c'est implémenté/tweaké dans les jeux ?).
    Dernière modification par Foudge ; 19/12/2012 à 23h50.

  4. #2704
    Merci pour vos réponses, Mogluglu et Tomaka.
    Il va me falloir un peu de temps pour les digérer, étant donné que l'héritage est pas ma tasse de thé.

  5. #2705
    +1 pour la suggestion de Mogluglu:
    - toutes les méthodes indépendantes du type de données --> dans la classe de base (dans le .h)
    - celles dont l'implémentation est indépendante du type de donnée --> dans la classe de base (cpp), les autres sont virtuelles pures.
    - la classe template dérive de la classe de base
    Arrivé la, tu as factorisé raisonnablement ton code en évitant de tout dupliquer. Et tu peux déclarer un pointeur sur la classe de base qui a l'exécution pointera sur la classe dérivée du type nécessaire.

    Après, il te faut introduire quelque chose de dynamique: une fonction de création d'objet qui créera un objet du bon type en fonction des données de ton volume.
    - la solution basique: une méthode de création d'objet qui contient un switch et créée le bon objet en fonction du type en appelant new. C'est vaguement un peu crade parce que ajouter un nouveau type nécessite de modifier le code unique ou est le switch; que ce code doit "connaitre" toutes les implémentations possibles etc... Mais bon, c'est vite fait...
    - la solution recommandée: une classe factory (je te laisse googler la chose). C'est plus complexe à mettre en place mais tu peux utiliser Boost::factory par exemple.

  6. #2706
    Je me rends compte d'un fossé à franchir, mais merci en tous cas pour vos indications.
    J'ai entretemps poussé ma logique précédente jusque au bout et terminé mon wrapper: j'ai besoin d'avancer dans l'applicatif, et surtout il faut aller au bout de sa connerie quand on veut progresser.

    En tous cas, ca fonctionne, et on peut notamment lui passer une fonction template locale en paramètre sans avoir à préciser le type.
    Je reprendrai au fur et à mesure mes lacunes pour améliorer mon code à fonctionnalité constante.


    Code:
    
    template <typename T>
    void
    fonction_binary_invert( Volume<T> &vol)
    {
      T* data = vol.get_data_linear();
      T lu;
    
      for (size_t i = 0; i < size; i++)
        {
          lu = data[i];
          data[i] = (lu) ? 0 : 1;
        }
    }
    
    
    int 
    main(int argc, char** argv)
    {
      // arg1: 
      usage(argc, argv);
      char* input_vol = argv[1];
      char* out_vol = argv[2];
      
      //Volume<float> volIn(input_vol);
      SuperVol volIn(input_vol);
    
      volIn.set_data_linear_mode(true);
      volIn.update_definitions();
      volIn.allocate();
      volIn.update_data();
    
    
      // wrap simple: binarize_data est méthode de clase Volume
      volIn.binarize_data(min);
    
      // wrap encore plus sale
      SUPERVOL_WRAP(volIn, fonction_binary_invert );
    
    //...
    }
    Dernière modification par vectra ; 20/12/2012 à 18h36.

  7. #2707
    Bon je poste ça ici aussi alors. Ma question :

    J'ai pas trop envie de polluer le topic de la prog' avec mes questions de noob donc je te la pose ici. Enfin si tu veux bien ! Mon cours passe (très) vite sur le débordement de capacité dans le chapitre de la représentation des nombres signés. Le prof parle longuement du complément à 2 et là donne l'exemple du débordement et c'est tout. Il explique même pas ce que ça engendre, comment on vérifie le calcul quand même. Du coup je vois pas bien comment ça fonctionne dans ce cas de figure.
    La réponse de Møgluglu :

    Une façon de voir le complément à 2, c'est que ça permet d'avoir une seule instruction d'addition qui marche aussi bien sur les nombres signés que non signés.

    Avec des nombres non signés, l'addition fonction modulo 2^n sur l'intervalle [0, 2^n-1]. Exemple : tu prends un ruban en papier, fais 16 cases numérotées de 0 à 15, et tu scotches les bouts ensemble pour faire un cylindre.

    En complément à 2, on va garder la même représentation pour les nombres de 0 à 2^(n-1)-1 parce que ça nous arrange, mais on interprète les autres comme des négatifs entre -2^(n-1) et -1. Exemple, tu reprends ton cylindre, mais cette fois tu re-numérotes à reculons en partant de zéro : -1 à la place de 15, -2 à la place de 14, jusqu'à l'extrémité opposée (entre -8 et 7).

    Tant que tu restes dans les nombres représentables, ton algo d'addition sur le cylindre est le même pour les signés et non signés.

    Pour les débordements : tu marques l'emplacement du bout de scotch avec un C (Carry) et le trait entre -8 et 7 de l'autre côté avec un O (Overflow). Quand tu fais une addition, si tu passes le trait C tu le notes dans un coin, si tu passes le trait O aussi.
    C et O sont des signaux en sortie de l'additionneur, qui sont mémorisés comme bits dans le registre de drapeaux (flags) dans la plupart des processeurs. Donc si tu veux savoir s'il y a eu un overflow (en complément à 2) tu testes le flag O, si tu veux savoir s'il y a eu une retenue (en unsigned) tu testes le flag C.

    Sinon tu peux balancer ces questions dans le topic de la prog, hein. Ça fera de mal à personne de réviser le complément à 2 et ça permettra à d'autre de répondre aussi.

  8. #2708
    J'ai rien compris.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  9. #2709
    J'avais compris ca de force en 1ère année de DUT, mais comme on ne s'en est jamais re-servi par la suite... (pas taper)

    Sinon, je crois avoir trouvé ce que je cherchais en tant qu'intro à Boost pour les nuls:
    http://quantlib.org/slides/dima-boost-intro.pdf

  10. #2710
    Citation Envoyé par vectra Voir le message
    Sinon, je crois avoir trouvé ce que je cherchais en tant qu'intro à Boost pour les nuls:
    http://quantlib.org/slides/dima-boost-intro.pdf
    Pro-tip : tout jusqu'à la page 50 est maintenant intégré dans le langage.
    Du coup c'est plutôt une intro à la librairie standard pour les nuls qu'il te faudrait
    Cela dit tu peux remplacer "boost::" par "std::" et t'as grosso-modo la même chose.

    Par contre je te déconseiller d'utiliser bind. Regarde plutôt du côté des lambdas (ceux du C++11, pas de boost), ça peut faire la même chose et c'est infiniment plus simple que bind.
    Rust fanboy

  11. #2711
    Oui, je me suis dit ca pour les lambda. A l'origine, je viens du scheme-lisp, donc ca fait partie des concepts que j'ai bien intégré.

    Par contre, la partie sur les smart-pointers n'était pas inutile sur le plan pédagogique, par exemple.

    Quant à std:: pour les nuls, je renouvelle mon appel à tutos récents: je prends tout, hein.

  12. #2712
    Citation Envoyé par trenks Voir le message
    Bon je poste ça ici aussi alors. Ma question :

    La réponse de Møgluglu :
    Heureusement que Meuh n'est pas prof (ou pas encore), j'avais deja compris le but du complément a 2 grace a mon prof d'archi mais pour ceux dont ce n'est pas le cas je ne pense pas qu'il comprenne avec ton explication. Ni ma phrase qui n'a aucun sens.


  13. #2713
    Donc quand il me demande la liste des valeurs possibles en 4 bits et leur représentation en complément à 2, ça va de -8 à 7 c'est ça ?

  14. #2714
    Ben la lib standard est pas très grande. T'as grosso-modo :
    - les containers : vector, list, array, deque, hash map, btree, etc.
    - les itérateurs (concept important)
    - les fonctions d'algorithmes, par exemple ton "fonction_binary_invert" je suis sûr que tu peux l'écrire en une seule ligne en utilisant une de ces fonctions
    - std::function pour stocker n'importe quel type de fonction
    - les streams (ifstream, cout, etc.) ; jette un coup d'oeil à boost.stream si tu veux les utiliser, c'est bien foutu
    - les smart pointers
    - les threads
    - les tuples
    - les strings (même si c'est aussi un container)
    - l'aléatoire
    - les exceptions (des classes d'exceptions standardisées, plus quelques fonctions très utiles comme std::current_exception())
    - les expressions régulières (mais les implémentations actuelles sont très lentes)

    La moitié de tout ça est arrivé avec le C++11, donc tous les tutos sur std::function, les smart pointers, les threads, les tuples, le random, les regex et les exceptions sont forcément récents.
    Et pour le reste, ça n'a pas beaucoup changé depuis, donc tout devrait être valable.
    Rust fanboy

  15. #2715
    Non, heureusement je n'enseigne plus.
    Je voulais faire un dessin au tableau mais j'avais pas de tableau et l'ASCII art ne passe pas dans les messages visiteurs.
    Seule solution donc, des ciseaux, un bic 4 couleurs et du scotch.

    ---------- Post added at 12h07 ---------- Previous post was at 12h05 ----------

    Citation Envoyé par trenks Voir le message
    Donc quand il me demande la liste des valeurs possibles en 4 bits et leur représentation en complément à 2, ça va de -8 à 7 c'est ça ?
    Vala.

    Tu vois greg, il a compris.

  16. #2716
    Citation Envoyé par trenks Voir le message
    Donc quand il me demande la liste des valeurs possibles en 4 bits et leur représentation en complément à 2, ça va de -8 à 7 c'est ça ?
    Oui

    C'est simple : t'as 16 valeurs en tout puisque 4 bits ; 8 valeurs dont le bit de signe est à 1, et 8 valeurs dont le bit de signe est à 0.
    Les premières ce sont les nombres négatives : de -1 à -8 (ça fait 8 valeurs, faut pas soustraire, attention au piège)
    Les secondes ce sont les nombres positifs et le zéro. Si tu enlèves le zéro il te reste 7 valeurs, donc de 1 à 7.

    Par contre j'ai rien compris non plus avec l'histoire du scotch.
    Rust fanboy

  17. #2717
    Je partage, je pense que ça peut en intéresser quelques uns :

    The talk is articulated in 3 parts. The first and last part are easy to get. The middle require much more background in optimization so some people may want to skip it. Don't skip the Q&A which has a lot of awesome advice.

    And here is an observation that some software engineers should think more often when writing their code:

    At scale, engineering cost is eclipsed by operational cost. It is the first time in human history quite literally that one engineer can control so much power [...] if you have a good thing, you multiply that on 10s of thousands of machine, we are talking about megawatts.
    Slides : http://www.slideshare.net/andreialex...for-c-15708507


  18. #2718
    J'ai noté les valeurs sur le tube de papier toilette, je suis paré pour comprendre le débordement.

  19. #2719
    Citation Envoyé par Tomaka17 Voir le message
    Ben la lib standard est pas très grande. T'as grosso-modo :
    - les containers : vector, list, array, deque, hash map, btree, etc.
    - les itérateurs (concept important)
    - les fonctions d'algorithmes, par exemple ton "fonction_binary_invert" je suis sûr que tu peux l'écrire en une seule ligne en utilisant une de ces fonctions
    - std::function pour stocker n'importe quel type de fonction
    - les streams (ifstream, cout, etc.) ; jette un coup d'oeil à boost.stream si tu veux les utiliser, c'est bien foutu
    - les smart pointers
    - les threads
    - les tuples
    - les strings (même si c'est aussi un container)
    - l'aléatoire
    - les exceptions (des classes d'exceptions standardisées, plus quelques fonctions très utiles comme std::current_exception())
    - les expressions régulières (mais les implémentations actuelles sont très lentes)

    La moitié de tout ça est arrivé avec le C++11, donc tous les tutos sur std::function, les smart pointers, les threads, les tuples, le random, les regex et les exceptions sont forcément récents.
    Et pour le reste, ça n'a pas beaucoup changé depuis, donc tout devrait être valable.
    T'oublies la métaprogrammation (type_traits, integral_constant), la reflection (rtti, type_traits), la gestoion date/heure/durée (clocks, duration), la localisation (locale), les atomics et la couche système (signals, error codes).
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  20. #2720
    Pour ma défense, j'ai tout cité de tête
    Rust fanboy

  21. #2721
    J'avoue que la métaprogrammation m'intéresse assez dans le lot.

  22. #2722
    Citation Envoyé par Froyok Voir le message
    Je partage, je pense que ça peut en intéresser quelques uns :



    Slides : http://www.slideshare.net/andreialex...for-c-15708507

    Quelqu'un peut commenter sur le "Prefer a[i++] over a[++i]" ? Je ne suis pas sûr de voir pourquoi le post-incrément est mieux.

    ---------- Post added at 12h23 ---------- Previous post was at 12h22 ----------

    Citation Envoyé par vectra Voir le message
    J'avoue que la métaprogrammation m'intéresse assez dans le lot.
    Dans la STL c'est encore assez limité. Mais Boost a des librairies dédiées assez monstrueuses (genre la MPL).

    C'est juste par curiosité ou bien est-ce que tu as des besoins spécifiques ?
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  23. #2723
    Cela dit la métaprogrammation, les atomics et la reflection, c'est pas trop le genre de trucs qu'on utilise quand on débute.

    Même chose pour les locale, ça sert presque à rien en pratique à part pour convertir entre UTF-8 et UTF-32 ou wchar_t.
    Aucun programmeur ne se fait chier à représenter l'argent ou l'heure dans le format de l'utilisateur. Et si t'as un beau logiciel avec GUI, tu préfèreras laisser le choix du format à l'utilisateur dans la configuration et faire ça manuellement.

    La date/heure c'est dans la librairie C et c'est super mal foutu.

    Le seul truc qu'il y a de bien dans le C++11 à ce niveau là c'est le remplacement de clock() par std::monotonic_clock et ses consoeurs.

    ---------- Post added at 12h32 ---------- Previous post was at 12h24 ----------

    Citation Envoyé par vectra Voir le message
    J'avoue que la métaprogrammation m'intéresse assez dans le lot.
    Tu devrais jeter un coup d'oeil aux itérateurs et aux fonctions dans <algorithm>.
    C'est pas vraiment de la métaprogrammation mais ça devrait te faire plaisir.

    Boost.MPF y a à peu près 2 personnes dans le monde qui l'utilisent pour faire quelque chose d'utile.
    Rust fanboy

  24. #2724
    Quelqu'un peut commenter sur le "Prefer a[i++] over a[++i]" ? Je ne suis pas sûr de voir pourquoi le post-incrément est mieux.
    Nos profs nous disent tout le contraire >_>


  25. #2725
    En fait Andrei l'explique dans le talk qui va avec.

    Pour les itérateurs c'est sans doute tout de même vrai parce que i++ retourne une copie de l'itérateur, copie qui peut être couteuse.

    Pour les index dans un tableau, en fait l'astuce c'est que i++ va découpler la dépendance entre le résultat du ++ et l'indice du tableau.
    Quand on écrit a[++i], l'index du tableau est le résultat de l'addition et donc il faut faire l'addition, lire le résultat et seulement à ce moment le CPU va savoir à quel index lire.
    Tandis que pour a[i++], l'index dans le tableau correspond à la valeur courante de i, et l'addition peut se faire après ou en parallèle, ou être prédite, on n'aura besoin du résultat qu'à l'itération suivante. Il explique que c'est plus efficace.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  26. #2726
    Citation Envoyé par rOut Voir le message
    Quelqu'un peut commenter sur le "Prefer a[i++] over a[++i]" ? Je ne suis pas sûr de voir pourquoi le post-incrément est mieux.
    Si ton compilateur est con au point de ne pas arriver à remonter l'incrémentation suffisamment en avance, alors tu crées une dépendance entre l'instruction d'incrémentation du pointeur et l'accès mémoire. Si en plus ton processeur est con au point de ne pas arriver à réordonner tout ça, ça peut ajouter 1 cycle au chemin critique. Et si tu compiles pour ARM, l'accès mémoire avec post-incrémentation peut se faire en une instruction au lieu de 2, donc tu gagnes 4 octets en taille de code. Autant dire que j'y crois moyen.
    [Grillé]

    Le bon conseil est de timer son code. Le reste... Je suis pas convaincu par la speed hierarchy non plus (FP add et FP mul c'est pareil, double et simple c'est pas pareil et extended precision faut juste pas l'utiliser, les conversions ça devait être comme ça sur PowerPC G4, mais maintenant non...)

  27. #2727
    Le bon conseil est de timer son code.
    C'est fou parce que c'est ce que tout le monde répète à tord et à travers et je vois incroyablement peu de gens qui le font pour de vrai. Les croyances et les idées reçues ont la vie dure.
    Perso, je doute de tout et je passe pour un chieur quand je demande des mesures pour prouver que tel truc est plus rapide .
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  28. #2728
    Je sais bien que ce n'est pas un truc de débutant, mais je suis déjà dans les templates jusqu'au cou là, déjà. Je me trompe peut-être, mais je ne me vois pas faire sans les templates pour traîter chaque type de données séparément.
    A part pour les optimisations SSE s'entend, mais ce n'est pas sur ma todo list des deux semaines à venir en tous cas.


    J'étais à fond dans les macros à l'époque du lisp, ca me manque assez et la métaprogrammation me semble de ce fait un concept plus naturel que pas mal d'autres.

    >Tomaka: bien sûr que ma fonction invert est mal fichue, mais j'avais juste besoin d'un exemple dans lequel on peut faire un traitement de données via le wrapper, ie sans ajouter une méthode à la classe de base puis l'ajouter dans la liste des méthodes wrappées.

    Ne faites pas attention si je viens à sortir des bêtises, je me concentre plutôt sur une liste de lectures pour cartographier une peu ce qui me manque. J'en reviens d'ailleurs un peu à une vieille question: y-a-t-il des facs et écoles d'ing qui dispensent des cours de C++ avancé qui soient à jour? J'irais bien sneaker les pdfs dans ce cas.

    >rOut: moi si, je chronomètre mon code avec boost, notamment pour vérifier que les optimisations OMP fonctionnent comme prévu.

  29. #2729
    Moi dans mon école d'ingé, notre prof de C++ nous faisait des cours exprès méta-programmation. Après c'était assez élémentaire, mais rien que d'aborder la factorielle compile-time ou l'unrolling de boucles par le compilateur ça ouvre un petit apperçu sur la puissance du truc. Je ne pense pas qu'il ait de PDF dispo publiquement, mais il nous conseillait des bouquins de Alexandrescu, Abrahams, et autres. Que je n'ai jamais lu BTW.

    ---------- Post added at 15h40 ---------- Previous post was at 15h19 ----------

    Si le LISP te parle, alors peut être que ces deux posts te plairont. C'est à propos des templates C++ vus comme un langage fonctionnel executé par le compilateur.
    http://bartoszmilewski.com/2009/09/0...made-easy-huh/
    http://bartoszmilewski.com/2009/10/2...-to-do-with-c/

    En plus Bartosz écrit en général des choses super intéressantes, et il y a de bonnes références si tu cherches de la lecture.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  30. #2730
    Pour ca, on avait macroexpand

Page 91 sur 334 PremièrePremière ... 41818384858687888990919293949596979899101141191 ... 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
  •