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 :

Tableaux C, classes et Templates


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
    Avril 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 17
    Par défaut Tableaux C, classes et Templates
    Bonjour,

    Je suis capable de recuperer la taille d'un tableau C via des templates, mais en 3 étapes, j'aurai voulu savoir s'il etait possible de le faire en une seule... Voici mon code (qui compile et marche) :
    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
     
    // Un parametre
    class Parametre
    {
    public:
        int pname;
        int param;
    };
    // Un ensemble de parametres
    class Parametres
    {
    public:
        std::vector<Parametre> params;
     
        template<std::size_t N>
        const Parametres& operator= (const Parametre (&params)[N])
        {
            for(const Parametre* i = params; i < params + N ; ++i)
            {
                this->params.push_back(*i);
            }
            return *this;
        }
    };
    // Instanciation - etape1 :
    Parametre p[] = 
    {
        {5,2},
        {1,2},
        {3,4}
    };
    // Instanciation - etape2 :
    Parametres params;
    // Instanciation - etape3 :
    params = p; // avec le p defini dans le bloc précédent
    Au final, je voudrais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // Le top : 
    params = {{5,2},{1,2}};
    // ou alors
    Parametres params = p;
    Cela est-il réalisable ?

    Merci d'avance pour vos réponses et conseils !
    B

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    A vrai dire, j'ai un peu de mal à comprendre le but de la manœuvre...

    Si tu crée un tableau de manière statique comme tu le fait dans ton exemple, tu as encore bien plus facile de "simplement" compter le nombre d'élément que tu y met, et de créer une variable qui représente cette valeur quelque part.

    Si tu crées ton tableau de manière dynamique, tu sera de toutes manières obligé de maintenir quelque part:
    • la taille allouée pour le tableau
    • le nombre d'éléments que tu as déjà inséré

    Bref, quoi qu'il en soit, tu connaitra les différentes valeurs à un moment où un autre

    Par contre, si l'idée est en fait de récupérer ces données dans une des collections de la STL (std::vector, par exemple), il faut savoir qu'elles proposent toutes une série de constructeurs assez sympa, comme, par exemple, celui qui prend un itérateur sur le début d'une collection et un itérateur sur... ce qui suit la fin de la collection.

    Ainsi, tu pourrait parfaitement envisager un code proche de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Parametre p[] = 
    {
        {5,2},
        {1,2},
        {3,4}
    };
    std::vector<Parametre> params(p, p+3);
    ou, si tu veux l'encapsuler dans une classe, avoir quelque chose proche de
    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
    class Parametres
    {
        public:
            Parametres (){} // constructeur par défaut
            template <typename iterator>
            Parametres(iterator beg, iterator end):tab_(beg,end){}
        private:
            std::vector<Parametre> tab_;
    };
    int main()
    {
        Parametre p[] = 
        {
            {5,2},
            {1,2},
            {3,4}
        };
        Parametres others(p,p+3);
    }
    Enfin, nouvelle norme te permet d'utiliser les vector de manière strictement identique à ce que l'on fait avec les tableaux C style:
    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
    #include <iostream>
    #include <vector>
    struct Parametre
    {
        int x;
        int y;
    };
    int main()
    {
        std::vector<Parametre> p =
        {
            {5,2},
            {1,2},
            {3,4}
        };
        std::cout<<"taille de p: "<<p.size()<<std::endl;
        for(size_t i=0;i<p.size();++i)
            std::cout<<p[i].x<<" "<<p[i].y<<std::endl;
    }
    Encore faut il alors que tu utilise un compilateur suffisamment récent pour pouvoir en tirer parti
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 17
    Par défaut
    Salut,

    Ta dernière proposition est intéressante, puisque si j'encapsule mon vector dans une classe (mais je me contente du coup d'un typedef), alors je suis capable de faire ceci :
    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
     
    class Parametre
    {
    public:
        int pname;
        int param;
    };
     
    typedef std::vector<Parametre> Parametres;
     
    // et donc en theorie :
    Parmetres p = 
    {
            {5,2},
            {1,2},
            {3,4}
    }; // exactement ce que je veux !
    Ceci dis je n'arrive pas à compiler ton dernier exemple ou ce que je propose (avec gcc4.4). Mais ma théorie est-elle fondée ?

    [EDIT] Ah si c'est bon je compile et mon design marche ! Pour info dans codeblocks : Project/Build Options ; Onglet Compiler settings puis cocher la case "have g++ follow the coming C++0x ISO C++ language standard [-std=c++0x] dans la liste de compiler Flags [/EDIT]

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Normal, std::vector ne supporte pas la liste d'initialization. Sauf avec la prochaine norme (C++0x)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 17
    Par défaut
    Ok donc maintenant j'ai ca :
    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
     
    #include <iostream>
    #include <vector>
    class Parametres
    {
        struct Parametre
        {
            int x;
            int y;
        };
    public:
        std::vector<Parametre> params;
     
        Parametres& operator= (const std::vector<Parametre> v)
        {
            this->params = v;
            return *this;
        }
    };
     
    int main()
    {
        Parametres p1;
        p1 = {
                {1,2},
                {3,4}
            };
    }
    qui ne compile pas et c'est exactement ce qu'il me faudrait (la structure parametre cachée)
    voila ce que me dis le compilo :

    In function ‘int main()’:

    main.cpp|26|error: no match for ‘operator=’ in ‘p1 = {{1, 2}, {3, 4}}’

    main.cpp|13|note: candidates are: Parametres& Parametres:: operator= std::vector<Parametres:: Parametre, std::allocator<Parametres:: Parametre> >)

    main.cpp|4|note: Parametres& Parametres:: operator=(const Parametres&)


    Puis-je contourner cette erreur ?
    Merci d'avance !

  6. #6
    Invité
    Invité(e)
    Par défaut
    Il suffit de remplacer le paramètre "vector" par "initializer_list" sans rien changer d'autre.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 17
    Par défaut
    Bien oui effectivement la liste d'initialisation fonctionne pour la construction mais pas pour l'affectation ?

    Voici un bout de code pour ceux que ca intéresse. Je me contenterai de la construction, cela me convient deja suffisamment. Merci à tous pour votre aide !
    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
    #include <iostream>
    #include <vector>
    #include <initializer_list>
     
    #include <GL/gl.h>
    using namespace std;
    class TexParametersi
    {
        struct TexParameteri
        {
            int target;
            int pname;
            int param;
        };
     
        std::vector<TexParameteri> _params;
     
    public:
     
        TexParametersi(){}
        // Ca marche
        TexParametersi(const std::initializer_list<TexParameteri>& p)
        {
            _params = p;
        }
        // Ca marche pas ?
        TexParametersi& operator= (const std::initializer_list<TexParameteri>& p)
        {
            this->_params = p;
            return *this;
        }
    };
     
    // Fonctionne
    TexParametersi tparams =
    {
        {GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST},
        {GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST}
    };
    // Ne fonctionne pas !
    TexParametersi tparams2;
    tparams2 =  {
                    {GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR},
                    {GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR}
                };

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

Discussions similaires

  1. Class, tableaux de class :(
    Par Naelhem dans le forum C++
    Réponses: 7
    Dernier message: 19/10/2006, 16h14
  2. [Tableaux] Interrogation classe et boucle
    Par masseur dans le forum Langage
    Réponses: 6
    Dernier message: 27/09/2006, 20h53
  3. Méthode template dans classe non template ?
    Par shenron666 dans le forum Langage
    Réponses: 12
    Dernier message: 04/09/2006, 17h50
  4. [Tableaux] [Débutant ) Classes
    Par Halobox dans le forum Langage
    Réponses: 5
    Dernier message: 12/01/2006, 15h50
  5. [Template] methode template d'une classe pas template
    Par bigquick dans le forum Langage
    Réponses: 8
    Dernier message: 25/03/2005, 15h09

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