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

C++ Discussion :

tableau de templatedont chaque elt est de type différent


Sujet :

C++

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut tableau de templatedont chaque elt est de type différent
    Bonjour a tous,

    Supposons disposer d'une classe dont un des membres est de type T quelconque:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <class T>
    class Toto {
    private:
          T _membre;
    public:
          Toto(const T & t): _membre(t) {}
          ~Toto() { }
          ....
    };
    Je souhaiterais disposer d'une structure de type tableau de Toto pour lequel chaque élément a potentiellement un type T différent. (genre tab[0] est un Toto<string>, tab[1] est un Toto<int> etc...
    Quelqu'un sait-il comment faire ca?

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Comment l'utiliserais-tu ?
    Comment ferais-tu pour savoir que le premier élément est une string, le 2° un int... ?

  3. #3
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Comment l'utiliserais-tu ?
    Comment ferais-tu pour savoir que le premier élément est une string, le 2° un int... ?
    Ca peut paraitre farfelu mais avec une enumération qui défini les types admissibles pour T (et qui pourrait être un membre de Toto).

    En fait, je cherche une alternative a une implémentation actuelle de gestion de fichiers de configuration qui utilise une union sur un des types données (bool, long, float et string) utilisée pour representer des valeurs des entrées d'un fichier de configuration. un tableau décrivant le contenu sémentique d'un fichier est utilisé (chaque élt est une structure incluant le nom de l'entrée, son type (venant d'une enumération) et sa valeur (de type l'union sont j'ai parlé précédemment).
    Je me demandais s'il n'y avait pas moyen de passer par des templates pour ca (je suis en train de refaire ma bibliothèque de gestion de fichier de configuration en utilisant boost::program_options)

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Perso, je ferais une classe parente et je stockerais en fait des pointeurs vers la classe parente, quitte à faire une dynamic_cast si c'est absolument utile.

  5. #5
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Miles
    Perso, je ferais une classe parente et je stockerais en fait des pointeurs vers la classe parente, quitte à faire une dynamic_cast si c'est absolument utile.
    Pas persuadé que ca marche car la classe parente sera forcément templatée et on devra donc l'instancier sur un type donné pour chaque éléments du tableau, non?

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Pas persuadé que ca marche car la classe parente sera forcément templatée
    Pas necessaire. Exemple :
    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
    class base
    {
      public :
      virtual void Get() =0;
    };
    template <class T>
    class Toto :public base{
    private:
          T _membre;
    public:
          Toto(const T & t): _membre(t) {}
          ~Toto() { }
          void Get() {cout<<_membre<<endl;}
    };
    //-------------------
    int main(
    {
       base * Tab[10];
      Toto<int> c(1);
      Toto<float> d(3.1416);
      Toto<string> e("hello");
      Tab[0] = &c;
      Tab[1] = &d;
      Tab[2] = &e;
      Tab[0]->Get();
      Tab[1]->Get();
      Tab[2]->Get();
      return 0;
    }

  7. #7
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    yep, effectivement. Merci.
    Pour les futurs lecteurs, je mets le code qui compile correctement:
    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
    #include <iostream>
    using namespace std;
     
    enum type_t { A, B };
     
    class Base {
    protected:
        type_t _t;
    public :
        Base(type_t t=A): _t(t) {}
        virtual ~Base() { }
        virtual void Get() = 0;
    };
     
    template<class T>
    class Toto : public Base {
    private:
          T _membre;
    public:
          Toto(const T & val, const type_t t=A): Base::Base(t), _membre(val) {}
          ~Toto() { }
          void Get() { cout << _membre << endl; }
    };
    //-------------------
    int main() {
        Base * Tab[3];
        Toto<int> c(1);
        Toto<float> d(3.1416);
        Toto<string> e("hello");
        Tab[0] = &c;
        Tab[1] = &d;
        Tab[2] = &e;
        for (int i=0; i<3; Tab[i++]->Get());
        return 0;
    }

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tant qu'à faire ça, pourquoi ne pas utiliser boost::any ?

  9. #9
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Loulou24
    Tant qu'à faire ça, pourquoi ne pas utiliser boost::any ?
    Je t'avouerais (honte a moi) découvrir les librairies Boost depuis hier.
    Merci pour le pointeur en tout cas.

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Y'a pas de honte
    Perso, je préfère passer par cette méthode

  11. #11
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Miles
    Y'a pas de honte
    D'ailleurs, en parlant de ca, j'utilise boost::program_options maintenant pour parser mes fichiers de conf et franchement, le tutorial du site (http://www.boost.org/doc/html/program_options.html) est vraiment à ch... pour pas dire autre chose. J'ai même rarement vu qch d'aussi mal expliquer.
    QQ'un a-t-il déjà utiliser ca et a un pointeur sur un bon howto? google n'est pas très loquace...

  12. #12
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Oui. J'avais dû faire ça en me basant sur les exemples donnés probablement.
    Je te laisse décortiquer et remplacer par ce qui te conviendra. Le code est simple et vraiment pas sorcier.
    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
    // Le fichier d'en-tête
    #ifndef PROJECTS_FOO_PARAMETERS_HPP__
    #define PROJECTS_FOO_PARAMETERS_HPP__
     
    #include <string>
    #include <boost/scoped_ptr.hpp>
     
    const int default_verbose_level          = 0;
    const std::string default_dest_dir       = "";
    const std::string default_regex_         = "\\.(?:foo|bar)";
     
    // singleton simpliste
    struct Parameters
    {
        int                 verbose_level()  const { return verbose_level_;}
        std::string const & dest_dir()       const { return dest_dir_;}
        std::string const & regex()          const { return regex_;}
     
        static Parameters & construct_instance(int argc, char ** argv);
        static Parameters & instance();
    private:
        int         verbose_level_;
        std::string dest_dir_;
        std::string regex_;
     
        static boost::scoped_ptr<Parameters> instance_;
        Parameters(int argc, char ** argv);
        Parameters() {}
        Parameters(Parameters const &);
        Parameters & operator=(Parameters const &);
    };
     
    #endif // PROJECTS_FOO_PARAMETERS_HPP__
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    // Le fichier à compiler
    #include <iostream>
    #include <cassert>
     
    #include <boost/program_options.hpp>
    namespace po = boost::program_options;
     
    #include "common.hpp"
    #include "parameters.hpp"
     
    /*===========================================================================*/
    /*==================================[ Parameters ]===========================*/
    /*===========================================================================*/
     
    boost::scoped_ptr<Parameters> Parameters::instance_(0);
     
    /*static*/ Parameters & Parameters::instance()
    {
        assert(instance_);
        return *instance_;
    }
     
    /*static*/ Parameters & Parameters::construct_instance(int argc, char ** argv)
    {
        assert(!instance_);
        instance_.reset(new Parameters(argc, argv));
        return instance();
    }
     
     
    Parameters::Parameters(int argc, char ** argv)
    : verbose_level_ (default_verbose_level)
    {
        // Some generic options
        po::options_description generic("Options");
        generic.add_options()
            ("version,V", "print version string")
            ("help,h", "produce help message")
            ;
     
        // Specific options
        po::options_description cw_opt_desc(PROGNAME " options");
        cw_opt_desc.add_options()
            ("verbose,v", po::value(&verbose_level_)->default_value(default_verbose_level)->implicit(),
             // PB: replace «arg» by «VERBOSE-LEVEL»
             "\n\t" "If VERBOSE-LEVEL is not specified, it is assumed to be 1."
             "\n\t" "== 0 : Silent execution [default]"
             "\n\t" ">= 1 : Display xxxx"
            )
     
            ("dest-dir,d", 
             po::value(&dest_dir_)->default_value(default_dest_dir)->implicit(),
             "Destination directory")
            ("regex,r", 
             po::value(&regex_)->default_value(default_regex_)->implicit(),
             "Regex used to determine xxxxxxx")
            ;
     
        // Merge the multiple sources
        po::options_description cmdline_options;
        cmdline_options.add(generic).add(cw_opt_desc);
     
        po::variables_map vm;        
        po::store(po::parse_command_line(argc, argv, cmdline_options), vm);
        po::notify(vm);    
     
        if (vm.count("help")) {
            std::cout << help << "\n";
            std::cout << cmdline_options << "\n";
            throw 1;
        }
        if (vm.count("version")) {
            std::cout << PROGNAME ", version " VERSION "\n";
            throw 0;
        }
     
        regex_ = "<\\s*A\\s+[^>]*href\\s*=\\s*[\"']([^\"']*" 
    	+ regex_ + ")[\"']";
        // Display some internal variables if verbose_level >= 2
        if (verbose_level_ >= 2) {
            std::cout <<  "verbose   = " << verbose_level_  << "\n";
            std::cout <<  "dst-dir   = " << dest_dir_       << "\n";
            std::cout <<  "rgx       = " << regex_    << "\n";
        }
    }
    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
    // le programme principal
    #include <iostream>
    #include "common.hpp"
    #include "parameters.hpp"
     
    /*===========================================================================*/
    /*==================================[ Main ]=================================*/
    /*===========================================================================*/
     
    int main (int argc, char **argv)
    {
        // 0- Load parameters
        if (1 == argc) {
            std::cout << USAGE "\n";
            std::cout << "       " PROGNAME " -h|--help\n";
            return 1;
        }
     
        try {
            // 0- Load parameters
            Parameters::construct_instance(argc, argv);
     
            // n- what the program is meant to do...
            do_stuff();
     
        } catch (std::exception & e) {
            std::cerr << PROGNAME << ": error: " << e.what() << "\n";
            return 1;
        } catch(int i) {
            return i;
        } catch(...) {
            std::cerr << PROGNAME << ": Exception of unknown type!\n";
        }
     
        return 0;
    }
    Tu vois là:
    - l'utilisation de paramètres optionnels qui sont vérifiés avant toute autre chose (-h)
    - l'utilisation de paramètres optionnels qui sont associés à des variables chaine et nombre, et qui disposent de valeurs par défaut
    - la construction en deux temps des options et arguments

    Ce qu'il manque:
    - l'utilisation d'un fichier d'options chargé via une plage itérable
    - le filtrage de ce fichier avec des streambuf filtrants -- pour ignorer les commentaires.
    - Divers fignolages

    C'est plutôt vite rajouté. Concentres-toi sur les exemples donnés.

  13. #13
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Merci :-)

Discussions similaires

  1. [9i] Parcourir un tableau dont l'index est de type VARCHAR2
    Par weejungle dans le forum PL/SQL
    Réponses: 3
    Dernier message: 14/09/2013, 16h32
  2. Composant : Savoir si un controle est de type combo ou Edit.
    Par Andry dans le forum Composants VCL
    Réponses: 9
    Dernier message: 08/09/2005, 16h08
  3. comment tester si une variable est de type indifined
    Par amelhog dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 10/08/2005, 09h32
  4. [langage] "@$" Quel est ce type de variable?
    Par YanK dans le forum Langage
    Réponses: 4
    Dernier message: 21/04/2005, 18h07
  5. Tableau d'objets de type différents
    Par Hell dans le forum C++
    Réponses: 9
    Dernier message: 11/01/2005, 22h57

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