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 :

Liste chainée template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1
    Par défaut Liste chainée template
    Bonjour à tous,

    Voici le problème :
    Je dispose d'une classe Data, dépendant d'un paramètre entier N.
    Je souhaite créer une classe DataContainer, dépendant aussi d'un paramètre entier N, telle qu'elle contienne une instance de chacune des classes Data<N>, Data<N-1>, ..., Data<0>.

    Comme je souhaite que DataContainer<N> contienne ces membres à la compilation, j'ai imaginé le code suivant basé sur une idée de pseudo liste chainée. L'accès au Kème élément se ferait au travers d'une méthode get<K>().

    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
    #include <iostream>
     
    template<int N> class Data
    {
    public:
        int foo[2*N];
    };
     
    template<> class Data<0>
    {
    public:
        int foo;
    };
     
    template<int K> struct DataList
    {
        Data<K> data;
        DataList<K-1> next;
    };
     
    template<> struct DataList<0>
    {
        Data<0> data;
    };
     
    template<int N> class DataContainer
    {
    public:
        template<int K> Data<K>& get()
        {
            return getList<K>().data;
        }
     
    private:
        template<int K> DataList<K>& getList()
        {
            return getList<K+1>().next;
        }
     
        DataList<N>& getList()
        {
            return dataList;
        }
     
    private:
        DataList<N> dataList;
    };
     
    int main()
    {
        DataContainer<1> dc;
     
        dc.get<0>().foo = 4;
        dc.get<1>().foo[0] = 3;
        dc.get<1>().foo[1] = 2;
     
        std::cout << dc.get<0>().foo << dc.get<1>().foo[1] << std::endl;
    }
    Le fait est que le compilateur n'arrive pas à distinguer
    de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<int K> DataList<K>& getList()
    et je me retrouve dans une récursion infinie.

    Auriez-vous une idée sur la bonne façon de procéder ?

    Merci de votre aide

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Je vois plusieurs solutions: soit tu passes par une classe du genre (std::/boost: integral_constant<N>, soit à l'aide de (std::/boost:enable_if, soit tu utilise une classe template imbriquée et spécialisée (pour le cas K=N) qui s'occupe de faire tout le boulot. En gros :
    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
     
    template<int N>
    class DataContainer
    {
    /* .... */
    // Soit
    public:
        template<int K> Data<K>& get()
        {
            return getList(std::integral_constant<K>()).data;
        }
    private:
     
        template<int K> DataList<K>& getList(std::integral_constant<K>)
        {
            return getList(std::integral_constant<K+1>()).next;
        }
     
        DataList<N>& getList(std::integral_constant<N>)
        {
            return dataList;
        }
    // Soit
    public:
        template<int K> Data<K>& get()
        {
            return getList<K>().data;
        }
    private:
     
        template<int K> 
        typename std::enable_if<K!=N, DataList<K>>::type& getList()
        {
            return getList<K+1>().next;
        }
     
        template<int K> 
        typename std::enable_if<K==N, DataList<K>>::type& getList()
        {
            return dataList;
        }
    // Ou encore
    public:
        template<int K> Data<K>& get()
        {
            return GetListHelper<K>::GetList(*this).data;
        }
    private:
         template<int K>
         friend GetListHelper<K>;
     
        template<int K>
        struct GetListHelper
        {
            static DataList<K>& GetList(DataContainer& self)
            {
                return GetListHelper<K+1>::GetList(self).next;
            }
        };
     
        template<>
        struct GetListHelper<N>
        {
            static DataList<N>& GetList(DataContainer& self)
            {
                 return self.dataList;
            }
        };
    };

Discussions similaires

  1. Pb Liste doublement chainée template
    Par ederf dans le forum Langage
    Réponses: 5
    Dernier message: 19/11/2006, 10h35
  2. Probleme arbre/liste chainée en template
    Par Raton dans le forum Langage
    Réponses: 1
    Dernier message: 07/11/2005, 16h09
  3. copie de liste chainée
    Par tomsoyer dans le forum C++
    Réponses: 15
    Dernier message: 31/08/2004, 18h20
  4. Trie liste chaine
    Par Congru dans le forum C
    Réponses: 2
    Dernier message: 30/03/2004, 19h05
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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