IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

registre parametres template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Par défaut registre parametres template
    bonjour ,
    pour mon application j'essaye de mettre en place un 'registre' pour stocker des valeurs diverses issues de l'interface pour les transmettre à des parties plus profondes de mon prog.
    Apres quelques essais je suis bloqué(int float), il doit y avoir plus simple et plus propre mais je ne sais pas comment faire.
    Si quelqu'un a une idée ça seait cool

    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #ifndef PARAMSREGISTER_H
    #define PARAMSREGISTER_H
    #include <string>
    #include <vector>
    #include <sstream>
    #include <stdlib.h>
     
    class ParamsRegister
    {
        public:
            ParamsRegister();
            virtual ~ParamsRegister();
     
            void set(std::string name, int value);
            void set(std::string name, float value);
     
            template <class T>
            T get( std::string name);
     
        protected:
        private:
            template<class T>
            std::string toString ( T value);
     
            enum etype { INT_TYPE, FLOAT_TYPE };
     
            struct param
            {
                std::string name;
                std::string value;
                etype type;
            };
     
            std::vector<param> mvParams;
    };
     
    template <class T>
    T ParamsRegister::get( std::string name)
    {
        for( auto i : mvParams)
        {
            if (i.name == name)
            {
                switch( i.type)
                {
                case INT_TYPE:
                    {
                        int v = atoi( i.value.c_str() );
                        return v;
                        break;
                    }
                case FLOAT_TYPE:
                    {
                        float v = atof( i.value.c_str() );
                        return v;
                        break;
                    }
                }
            }
        }
    }
     
    template<class T>
    std::string ParamsRegister::toString ( T value)
    {
        std::stringstream sstr;
        sstr << value;
        return sstr.str();
    }
     
    #endif // PARAMSREGISTER_H
    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #include "ParamsRegister.h"
     
    ParamsRegister::ParamsRegister()
    {
        //ctor
    }
     
    ParamsRegister::~ParamsRegister()
    {
        //dtor
    }
     
    void ParamsRegister::set(std::string name, int value)
    {
        param p;
        p.type = INT_TYPE;
        p.name = name;
        p.value = toString( value);
        mvParams.push_back( p);
    }
     
    void ParamsRegister::set(std::string name, float value)
    {
        param p;
        p.type = FLOAT_TYPE;
        p.name = name;
        p.value = toString( value);
        mvParams.push_back( p);
    }
    Merci.

  2. #2
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct param
    {
      union { int int_value; float float_value };
      etype type;
    };
     
    std::map<std::string, param> params;
    Ou avec boost :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<std::string, boost::variant<int, float>> params;

  3. #3
    Membre éclairé Avatar de SKone
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 333
    Par défaut
    Au moment où tu veux setter tes Int ou Float le type est connu.
    Pas vraiment besoin d'union et de tester le type à chaque fois.
    Juste 2 maps.
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::map< std::string, int > m_IntegerRegisters;
    std::map< std::string, float > m_FloatRegisters;
    Et si tu peux avoir un CRC32 de tes strings, via une hash map ou par toi même cela accélérera rapidement ton code:
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::map< unsigned int, int > m_IntegerRegisters;
    std::map< unsigned int, float > m_FloatRegisters;
    Tu peux generaliser avec un:
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template < typename Type >
    using Register = std::map< unsigned int, Type >;
    // Ou alors
    template < typename Type >
    using Register = std::map< std::string, Type >;

    Ton registre deviens:
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Register< float > m_FloatRegisters;
    Register< int > m_IntegerRegisters;
    // ...

  4. #4
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Citation Envoyé par SKone Voir le message
    Et si tu peux avoir un CRC32 de tes strings, via une hash map ou par toi même cela accélérera rapidement ton code:
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::map< unsigned int, int > m_IntegerRegisters;
    std::map< unsigned int, float > m_FloatRegisters;
    Dans ce cas, utiliser directement std::unordered_map<std::string, T>.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Par défaut
    bonjour,
    merci de vos eclaircissemnets, mais en fait je voudrais juste pouvoir faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    // debut application
    Register  reg; 
     
    // initialisation avec des valeurs par defauts
    reg.set("nb_cube", 10);
    reg.set("couleur_cube", glm::vec3(1.0,0.0,0.0));
    reg.set("dist_cube", 21.53 );
    ...
     
    // modif par inertface
    reg.set("nb_cube", 12);
    ...
     
     
    // boucle de rendu
    int nb = reg.get("nb_cube");
    glm::vec3 color = reg.get("couleur_cube");
    float dist = reg.get("dist_cube");
    ...
    bien_sur le reg sera passé par reference ou quelque-chose comme ça dans le vrai code.
    En fait le but ce seait d'avoir un objet qui puisse stocker (set) les valeurs des parametres de types differents et les restituer à la demande (get).
    Variadic template??
    En tout cas merci.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu n'as que deux cas possibles:
    • Les types possibles sont connus, et en nombre fini.
    • Ce n'est pas le cas


    Dans le premier cas, tu va pouvoir utiliser la surcharge du set, mais pas pour le get (le type de retour n'ai pas un changement suffisant)

    En implémentation, tu aura soit une ma<string, variant<int, double, vect3f, ...>> soit plusieurs maps. (<string, int>, <string, double>...)
    et les getT/set qui pointent sur le bon type.

    Dans le second, tu auras une interface similaire à boost::any (get<T>)
    Et l'implémentation sera une map<string, any>.

    J'ai un gros penchant pour les plusieurs maps.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Par défaut
    Bonsoir,
    Les Types sont connus et en nombre fini.
    Boost::any pourrait convenir je vais creuser de ce cote, pourquoi lui préférer la solution avec plusieurs map qui semble plus lourde à gérer, si any semble plus generique?
    Dans la doc de boost, il y a un truc intéressant :


    The following type, patterned after the OMG's Property Service, defines name-value pairs for arbitrary value types:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct property
    {
        property();
        property(const std::string &, const boost::any &);
     
        std::string name;
        boost::any value;
    };
     
    typedef std::list<property> properties;
    Il faut que je vois comment je peux utiliser ça.
    Encore merci pour l'info.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problemes avec les Parametres template
    Par hardcpp dans le forum C#
    Réponses: 4
    Dernier message: 07/08/2012, 05h32
  2. Plusieurs parametres template
    Par jfouche dans le forum Langage
    Réponses: 11
    Dernier message: 03/05/2009, 13h58
  3. impossible de déduire un parametre template ?
    Par NiamorH dans le forum Langage
    Réponses: 3
    Dernier message: 26/11/2007, 19h33
  4. Parametre template et typedef d'une base
    Par NiamorH dans le forum Langage
    Réponses: 4
    Dernier message: 21/11/2007, 03h09
  5. un parametre de template qui est refuser
    Par lichman dans le forum Langage
    Réponses: 11
    Dernier message: 22/01/2007, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo