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 :

Implémentation d'un tuple dynamique.


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Implémentation d'un tuple dynamique.
    Bonjour, j'essaye d'implémenter un tuple dynamique mais je rencontre un problème, en fait, je n'arrive pas à affecter le bon type pour l'élément du tuple dynamique :

    Comme pour les tuples statique je crée une structure Element mais à part que là je n'ai pas de queue étant donné que je ne connais pas le nombre d'éléments à l'avance du tuple, je ne peux pas créer les élément avec un template variadique car ce sont des tuples à un élément, l'index 0 pointe vers le tuple lui même (tuple vide), l'index 1 point vers le 1er élément du tuple, etc..., tout comme std::tuple à part que là comme la taille est variable je défini l'index pour chaque élément du tuple et la taille à la compilation, comme ceci :

    Bref voici ma structure Element :

    Code cpp : 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
     
    /**Define an index to a type of an element.*/
    template <std::size_t I, class... T> class Element;
    /**Define the index to the first tuple instance
    *The type of the tuple and the type of the first element of the tuple are stored.
    */
    template<typename H, std::size_t>
    class DynamicTuple;
    template <class H> class Element <0, DynamicTuple<H, 0>> {
        public :
        typedef H& Type;
        typedef DynamicTuple<H, 0> VType;
    };
     
    template <std::size_t I, class H>
    class Element<I, DynamicTuple<H, I>>
      : public Element<I - 1, DynamicTuple<H, I-1> >
    {
    };

    Et voici ma structure dynamic tuple :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    template <class T, size_t i=0>
    struct DynamicTuple {
    public :
        template <typename A>
        static void add_element(A element) {
            typedef typename Element<size+1, DynamicTuple<T, size+1>>::Type A;
        }
        static constexpr int getSize() {
            return size;
        }
    private :
        static constexpr int size = i;
    };

    Le template est juste un type qui sert à identifier le tuple dynamique. (En général c'est la classe qui contient le tuple dynamique)

    Le problème est que je lorsque je veux récupérer le type d'un élément, il me renvoie toujours le type de la classe contenant le tuple dynamique et je ne comprend pas pourquoi :

    Code cpp : 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
     
    template <typename L, int I=0, bool B=true>
    struct get_type {
    };
    template <typename L, int I>
    struct get_type <L, I, true> {
        static typename Element<I, L>::Type element (L list, int n) {
            if (n == 0)
                return Element<I, L>::Type;
            constexpr bool isGreater = ((int) (I+1) > DynamicTuple<L, I+1>::getSize());
            return get_type<L, I+1, isGreater>::get_type(list, n);
        }
    };
    template <typename L, int I>
    struct get_type <L, I, false> {
        static typename Element<I, L>::type element (L list, int n) {
            //assert(false);
        }
    };

    Voilà alors j'aimerais savoir comment lui spécifier que Element<1, DynamicTuple<MaClasse>>::Type est de type A et non pas de type MaClasse.
    Et aussi si possible comment instancier cet élément.
    Quand j'essaye, j'ai une erreur en compilation. (Vu que type est pas le bon)

  2. #2
    Invité
    Invité(e)
    Par défaut
    J'ai essayé ça :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename A>
        static void add_element(A type) {
            typedef typename Element<size+1, DynamicTuple<T, size+1>>::Type Type;
            Type newType = (Type) type;
        }

    Mais ça ne marche pas mieux. :/

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bon je pense que j'ai compris, en fait il faut que je trouve un moyen de référencer l'élément suivant à partir de l'élément actuel un peut comme le principe des listes chaîné et que je parcours chaque élément.

    Mais je ne vois pas du tout comment faire ça avec des classes templates.

    Donc si quelqu'un à une solution je suis preneur.

  4. #4
    Invité
    Invité(e)
    Par défaut Problème d'ambiguité.
    Bonsoir.

    Je suis finalement parvenu à trouvé une solution mais j'ai un dernier problème :

    C'est un problème d'ambiguité, en fait j'ai deux spécialisation pour la classe DynamicTuple comme ceci :

    Code cpp : 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
     
    template <class H>
    struct DynamicTuple <H, 0> {
    public :
        DynamicTuple() {
            typedef typename Element<size, DynamicTuple<H, size>>::Type Type1;
            typedef typename Element<size, DynamicTuple<H, size>>::VType Type2;
            Type2 newtype2 = *this;
        }
     
        template <typename A>
        static void add_element(A* element) {
            DynamicTuple<A,size+1> *dt = new DynamicTuple<A, size+1>();
            typedef typename Element<size+1, DynamicTuple<A, size+1>>::Type Type1;
            typedef typename Element<size+1, DynamicTuple<A, size+1>>::VType Type2;
            Type1 newtype1 = *element;
            Type2 newtype2 = *dt;
        }
        static constexpr size_t getSize() {
            return size;
        }
    private :
        static constexpr size_t size = 0;
    };
    template <class H, size_t I>
    struct DynamicTuple<DynamicTuple<H, I>, I> : public DynamicTuple<H, I-1> {
        template <class = typename std::enable_if<(I > 0)>::type>
        DynamicTuple() {
        }
        template <class = typename std::enable_if<(I > 0)>::type>
        static constexpr size_t getSize() {
            return size;
        }
        static constexpr size_t size = I;
    };

    Et j'ai un typedef sur un DynamicTuple dans une autre structure, le problème survient quand je veux utiliser la fonction statique getSize() sur le typedef, il me renvoie une erreur d'ambiguité :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    typedef typename Element<I+1, DynamicTuple<L, I+1>>::VType NextType;
            constexpr bool isGreater = ((int) (I+1) > NextType::getSize());
            return typelist<NextType, T, I+1, isGreater>::exists(list, type);

    Comment résoudre se problème ?
    J'ai entendu parlé de SFINAE mais je ne vois pas trop bien comment l'utiliser ici.

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Un code reproductible et l'erreur serai un plus

    Par contre, je ne vois pas l’intérêt du constructeur.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Salut,

    J'ai résolu le problème d'ambiguité en rajoutant un 4ème paramètre template mais j'ai du arrêté car plantage du compilateur...

    Bref pour réussir à faire ce que je veux faire il faudrait arriver à passer à une classe (par exemple la classe template I+1), le type de l'élément de la classe I et arriver à le récupérer sans que la classe I+1 aie un paramètre template de du type de l'élement I.

    Bref je pense pas que ça soit possible.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bon j'ai essayé quelque chose comme ceci
    Code cpp : 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
     
    template<typename B>
    class DynamicTuple {
        private :
        std::map<std::string, B*(*)()> elements;
        template<typename E>    B * createInstance() { return new E; }
     
        public :
        template <typename E>
        void addElement(std::string type, E element) {
            elements[type] = &createInstance<std::remove_pointer<E>>;
        }
        template <typename E>
        bool exists (E element) {
            typename std::map<std::string, B*(*)()>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (std::is_same<decltype(it->second()), E>::value)
                    return true;
            }
            return false;
        }
        template <typename E>
        std::string getType(E element) {
            typename std::map<std::string, B*(*)()>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (it->second() == element)
                    return it->first;
            }
        }
        auto get(std::string type) -> decltype(elements[type]()) {
            return elements[type]();
        }
    };

    Mais ça ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/local/include/odfaeg/Core/tuple.h||In instantiation of ‘void odfaeg::DynamicTuple<B>::addElement(std::string, E) [with E = Base*; B = odfaeg::Serializable; std::string = std::basic_string<char>]’:|
    /usr/local/include/odfaeg/Core/serialization.h|13|required from ‘odfaeg::Serializable::Serializable(D*) [with D = Base]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|12|required from here|
    /usr/local/include/odfaeg/Core/tuple.h|25|error: no matches converting function ‘createInstance’ to type ‘std::map<std::basic_string<char>, odfaeg::Serializable* (*)(), std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, odfaeg::Serializable* (*)()> > >::mapped_type {aka class odfaeg::Serializable* (*)()}’|
    /usr/local/include/odfaeg/Core/tuple.h|20|note: candidate is: template<class E> B* odfaeg::DynamicTuple<B>::createInstance() [with E = E; B = odfaeg::Serializable]|
    ||=== Build failed: 1 error(s), 3 warning(s) (0 minute(s), 4 second(s)) ===|

  8. #8
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    C'est moche, non efficace et pas sûr .

    Tu veux faire quoi de ta tuple dynamique ? Accès par indice ou par type ?
    tuple_index

  9. #9
    Invité
    Invité(e)
    Par défaut
    Accès par nom du type.

    J'ai enfin trouvé une solution mais j'ai toujours un problème de compilation :

    Code cpp : 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
     
    template <typename B>
    class DynamicTupleBaseElement {
          public :
          virtual B* get() = 0;
    };
    template<typename E, typename B>
    class DynamicTupleElement : public DynamicTupleBaseElement<B> {
        public :
        DynamicTupleElement(E* element) {
            this->element = element;
        }
        E* get() {
           return element;
        }
        E* element;
    };
    template <typename B>
    class DynamicTuple {
        private :
        typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator f (std::string type) {
            return elements.find(type);
        }
        std::map<std::string, DynamicTupleBaseElement<B>*> elements;
        public :
        template <typename E>
        void addElement (std::string type, E element) {
            DynamicTupleBaseElement<B>* base_element = new DynamicTupleElement<E, B>(element);
            elements[type] = base_element;
        }
        template <typename E>
        bool exists (E element) {
            typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (std::is_same<decltype(it->second->get()), E>::value)
                    return true;
            }
            return false;
        }
        template <typename E>
        std::string getType(E element) {
            typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (std::is_same<decltype(it->second->get()), E>::value)
                    return it->first;
            }
        }
        auto get(std::string type) -> decltype(this->f(type)->second->get()) {
            return elements[type]->get();
        }
    };
    }

    Voici l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/local/include/odfaeg/Core/tuple.h||In instantiation of ‘class odfaeg::DynamicTupleElement<Base*, odfaeg::Serializable>’:|
    /usr/local/include/odfaeg/Core/tuple.h|43|required from ‘void odfaeg::DynamicTuple<B>::addElement(std::string, E) [with E = Base*; B = odfaeg::Serializable; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/serialization.h|13|required from ‘odfaeg::Serializable::Serializable(D*) [with D = Base]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|12|required from here|
    /usr/local/include/odfaeg/Core/tuple.h|28|error: conflicting return type specified for ‘E* odfaeg::DynamicTupleElement<E, B>::get() [with E = Base*; B = odfaeg::Serializable]’|
    /usr/local/include/odfaeg/Core/tuple.h|20|error:   overriding ‘B* odfaeg::DynamicTupleBaseElement<B>::get() [with B = odfaeg::Serializable]’|
    ||=== Build failed: 2 error(s), 4 warning(s) (0 minute(s), 3 second(s)) ===|
    Et je sais pas comment la résoudre. :/

    B est une classe de base qui sert juste d'identifiant pour le tuple et E est un object dérivé de B. (D'ou l'utilisation de mes template et de la fonction virtuelle dont le type de retour est covariant.
    Dernière modification par Invité ; 04/08/2014 à 16h41.

  10. #10
    Invité
    Invité(e)
    Par défaut
    J'ai essayé ceci :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename B>
    class DynamicTupleBaseElement {
      public :
          virtual auto get() = 0;
    };

    Mais ça ne résoud pas le problème et gcc me renvoie un bug.

    C'est moi ou c'est un bug de gcc ?

    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
     
    In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/serialization.h:3:0,
                     from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h:7,
                     from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/archive.cpp:1:
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/../Core/tuple.h:20:28: warning: ‘get’ function uses ‘auto’ type specifier without trailing return type [enabled by default]
           virtual auto get() = 0;
                                ^
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/../Core/tuple.h: In instantiation of ‘class odfaeg::DynamicTuple<odfaeg::Serializable>’:
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/serialization.h:12:22:   required from here
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/../Core/tuple.h:63:10: error: use of ‘auto odfaeg::DynamicTupleBaseElement<B>::get() [with B = odfaeg::Serializable]’ before deduction of ‘autoauto get(std::string type) -> decltype(this->f(type)->second->get()) {
              ^
    ‘
    Internal compiler error: Error reporting routines re-entered.
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <file:///usr/share/doc/gcc-4.8/README.Bugs> for instructions.
    Preprocessed source stored into /tmp/ccsjaihe.out file, please attach this to your bugreport.
    make[2]: *** [src/odfaeg/Core/CMakeFiles/sfgl-core.dir/archive.cpp.o] Erreur 1
    make[1]: *** [src/odfaeg/Core/CMakeFiles/sfgl-core.dir/all] Erreur 2
    make: *** [all] Erreur 2

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Tu as définitivement un problème d’approche dans ce que tu veux faire.

    Tu veux gérer à la compilation des choses qui dépendent de ton exécution. Tu peux tourner le problème dans tous les sens, ça ne marchera pas, ça n’est pas fait pour. Je ne peux que t’encourager à revoir ton approche parce que là, tu fonces dans un mur.

    La solution que tu voudrais (si j’ai bien suivi) consiste probablement à ajouter un mécanisme d’introspection à toutes tes classes, et probablement des fabriques pour pouvoir instancier des objets à partir des infos récupérées. Tu n’arriveras probablement pas à faire un équivalent de ça avec l’approche que tu as choisie.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Tu as définitivement un problème d’approche dans ce que tu veux faire.
    Tu veux gérer à la compilation des choses qui dépendent de ton exécution.
    En effet c'est ce que je veux faire afin d'éviter de devoir passer par une factory et par un système d'introspection.

    Peut être ai je trop l'habitude des languages interprétés comme le java par exemple.

    Tu veux gérer à la compilation des choses qui dépendent de ton exécution. Tu peux tourner le problème dans tous les sens, ça ne marchera pas, ça n’est pas fait pour. Je ne peux que t’encourager à revoir ton approche parce que là, tu fonces dans un mur.
    Peut être pas forcément, j'ai essayer l'annotation override :

    http://stackoverflow.com/questions/4...tual-functions

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    virtual E* get() const override {
         return element;
    }

    Mais ça n'a pas l'air de fonctionner avec gcc.

    Pourtant B et E sont covariant donc le type de retour ne devrait pas poser de problème et il doit savoir ça a la compilation non ?

    Code cpp : 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 Base : public odfaeg::Serializable {
    public :
        Base() : odfaeg::Serializable() {}
        Base(std::string name) : odfaeg::Serializable(this) {
            this->name = name;
        }
        std::string getName() {
            return name;
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            ar & name;
        }
    private :
        std::string name;
    };

    Dans ce cas ici b est la classe Serializable et E la classe Base :

    Code cpp : 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
     
    #ifndef ODFAEG_SERIALIZATION
    #define ODFAEG_SERIALIZATION
    #include "../Core/tuple.h"
    #include <iostream>
    #include <typeinfo>
    namespace odfaeg {
    class Serializable {
        public :
        Serializable() {}
        template <typename D>
        Serializable(D* type) {
            if (!typelist.exists(type)) {
                typelist.addElement(typeid(type).name(), type);
            } else {
                type_name = typelist.getType(type);
            }
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            std::cout<<"serialize : "<<std::endl;
        }
        std::string type_name;
        static DynamicTuple<Serializable> typelist;
    };
    }
    #endif // SERIALIZATION

  13. #13
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Peut être pas forcément, j'ai essayer l'annotation override :
    override ne fait rien d’autre que rajouter une erreur de compilation si la fonction n’existait pas dans la classe de base. Très utile lors de refactoring, mais complètement inutile dans ton cas.

    Sinon, les types de retour covariant sont supportés depuis longtemps et opérationnels sur tous les compilateurs modernes : c’est probablement l’utilisation que tu essaies d’en faire qui n’est pas bonne. Je pense que là encore, le soucis est que tu veux résoudre cela à la compilation alors que cette information n’existe qu’à l’exécution.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Oui il ne sait pas que E hérite de B mais si j'utilise l'héritage multiple il ne devrait plus me renvoyer d'erreur non ? (Ce pattern s'appelle le pattern visitor)

    Code cpp : 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
     
    template <typename B>
    class DynamicTupleBaseElement : public std::remove_pointer<B> {
      public :
          DynamicTupleBaseElement() {
     
          }
          virtual B* get() const = 0;
    };
    template<typename E, typename B>
    class DynamicTupleElement : public std::remove_pointer<E>, public DynamicTupleBaseElement<B> {
        public :
        DynamicTupleElement(E element) {
            this->element = element;
        }
        virtual E* get() const {
           return element;
        }
        E* element;
    };

    Mais il ne comprend toujours pas que B et E sont covariant hors que pourtant avec l'héritage multiple ils le sont. (Ok dans la librairie il ne connait pas B et E vu que je défini les classes en dehors de la librairie mais normalement si il sait que B hérite de E ça devrait lui suffire non ?

    Bref je comprend vraiment pas pourquoi il me renvoie toujours une erreur d'overriding sur la fonction virtuelle là. :/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/local/include/odfaeg/Core/tuple.h||In instantiation of ‘class odfaeg::DynamicTupleElement<Base*, odfaeg::Serializable>’:|
    /usr/local/include/odfaeg/Core/tuple.h|46|required from ‘void odfaeg::DynamicTuple<B>::addElement(std::string, E) [with E = Base*; B = odfaeg::Serializable; std::string = std::basic_string<char>]’|
    /usr/local/include/odfaeg/Core/serialization.h|13|required from ‘odfaeg::Serializable::Serializable(D*) [with D = Base]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|12|required from here|
    /usr/local/include/odfaeg/Core/tuple.h|31|error: conflicting return type specified for ‘E* odfaeg::DynamicTupleElement<E, B>::get() const [with E = Base*; B = odfaeg::Serializable]’|
    /usr/local/include/odfaeg/Core/tuple.h|23|error:   overriding ‘B* odfaeg::DynamicTupleBaseElement<B>::get() const [with B = odfaeg::Serializable]’|
    ||=== Build failed: 2 error(s), 4 warning(s) (0 minute(s), 7 second(s)) ===|

  15. #15
    Invité
    Invité(e)
    Par défaut
    Ha ça va j'ai compris (problème avec les pointeurs) j'ai donc corrigé :

    Code cpp : 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
     
    #ifndef TUPLE
    #define TUPLE
    #include <map>
    #include <vector>
    #include <iostream>
     
    namespace odfaeg {
    namespace helper {
    template <int...> struct seq {};
    template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {
     
    };
    template<int ...S> struct gens<0, S...>{
        typedef seq<S...> type;
    };
    }
    template <typename B>
    class DynamicTupleBaseElement : public std::remove_pointer<B> {
      public :
          DynamicTupleBaseElement() {
     
          }
          virtual B get() const = 0;
    };
    template<typename E, typename B>
    class DynamicTupleElement : public std::remove_pointer<E>, public DynamicTupleBaseElement<B> {
        public :
        DynamicTupleElement(E element) {
            this->element = element;
        }
        virtual E get() const {
           return element;
        }
        E element;
    };
    template <typename B>
    class DynamicTuple {
        private :
        typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator f (std::string type) {
            return elements.find(type);
        }
        std::map<std::string, DynamicTupleBaseElement<B>*> elements;
        public :
        template <typename E>
        void addElement (std::string type, E element) {
            DynamicTupleBaseElement<B>* base_element = new DynamicTupleElement<E, B>(element);
            elements[type] = base_element;
        }
        template <typename E>
        bool exists (E element) {
            typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (std::is_same<decltype(it->second->get()), E>::value)
                    return true;
            }
            return false;
        }
        template <typename E>
        std::string getType(E element) {
            typename std::map<std::string, DynamicTupleBaseElement<B>*>::iterator it;
            for (it = elements.begin(); it != elements.end(); it++) {
                if (std::is_same<decltype(it->second->get()), E>::value)
                    return it->first;
            }
        }
        auto get(std::string type) -> decltype(this->f(type)->second->get()) {
            return elements[type]->get();
        }
    };
    }
    #endif // TUPLE

    Code cpp : 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
     
    #ifndef ODFAEG_SERIALIZATION
    #define ODFAEG_SERIALIZATION
    #include "../Core/tuple.h"
    #include <iostream>
    #include <typeinfo>
    namespace odfaeg {
    class Serializable {
        public :
        Serializable() {}
        template <typename D>
        Serializable(D* type) {
            if (!typelist.exists(type)) {
                typelist.addElement(typeid(type).name(), type);
            } else {
                type_name = typelist.getType(type);
            }
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            std::cout<<"serialize : "<<std::endl;
        }
        std::string type_name;
        static DynamicTuple<Serializable*> typelist;
    };
    }
    #endif // SERIALIZATION

    Mais maintenant j'ai une erreur de segmentation!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #0 0x433385	get(type=..., this=<optimized out>) (/usr/local/include/odfaeg/Core/tuple.h:67)
    #1 ??	odfaeg::OTextArchive::operator<< (this=this@entry=0x7fffffffe070, serializable=...) (/usr/local/include/odfaeg/Core/archive.h:52)
    #2 0x42f7b8	main(argc=<optimized out>, args=<optimized out>) (/home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp:71)
    L'erreur viendrais d'ici :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void operator<<(Serializable& serializable) {
           auto object = serializable.typelist.get(serializable.type_name);
           save(*object);
        }

    Avec le mot clé auto.

  16. #16
    Invité
    Invité(e)
    Par défaut
    Mwai, il perd le type de E, au départ E est bien de type pointeur base quand je l'affiche avec typeinfo mais quand j'appelle get, E est un autre type. (PN6odfaeg12SerializableE)

  17. #17
    Invité
    Invité(e)
    Par défaut
    Arf non j'ai essayé de faire ça sans passer par la classe Serializable et passer directement par la classe dynamic tuple :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    odfaeg::Serializable s;
        odfaeg::DynamicTuple<odfaeg::Serializable*> dt;
        Base b ("A base object");
        dt.addElement("Base", &b);
     
        std::cout<<dt.get("Base")->getName()<<std::endl;

    Mais ça me renvoie un objet de type Serializable hors que c'est pas ce que je veux moi je veux un pointeur sur un objet de type base.

  18. #18
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    La notion de tuple dynamique me fait directement penser à du vector<any>
    Le fait que tu veuilles pas utiliser ça me laisse perplexe..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  19. #19
    Invité
    Invité(e)
    Par défaut
    Non je veux pas utiliser boost::any car je suis obligé de connaitre le type en compilation pour le any_cast.

  20. #20
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    A ce compte-là pourquoi s'em****** à faire du C++ quand Python permet ça très trivialement ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [Forth] Implémentation des structures dynamiques
    Par <Zer0> dans le forum Autres langages
    Réponses: 14
    Dernier message: 28/01/2009, 23h01
  2. Réponses: 9
    Dernier message: 16/10/2008, 02h54
  3. Réponses: 6
    Dernier message: 30/06/2006, 00h09
  4. Réponses: 2
    Dernier message: 05/05/2006, 16h44
  5. [JSF] Implémentation d'un formulaire dynamique
    Par Fleep dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/03/2005, 19h00

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