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. #21
    Invité
    Invité(e)
    Par défaut
    Oui je pense que je devrais passer à python plutôt.

    Ici on dirait qu'il me recrée une fonction get avec un objet de type Base dans ma classe DynamicTupleElement et il cast l'objet de type element en un objet de type base. (Hors c'est pas ce que je veux)

    Python est assez rapide pour les jeux ???

    Bref je vais devoir recoder tout mes moteur mais c'est pas très grave je pense que pour la sérialization et le transfert et la sauvegarde de données ça serait beaucoup plus simple de le faire en python.

  2. #22
    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
    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.
    Tu n’as pas compris comment marchent les types de retour covariants. Là encore, tout est résolu à la compilation, et c’est ce qui fait que ton approche ne fonctionne pas.

    Pour faire simple, soit deux classes, Base et Derived, qui ont une méthode foo(). virtual Base::foo() renvoie un Base*, Derived::foo() override renvoie un Derived*.

    Cela nous donne globalement les choses suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Base b;
    Derived d;
    Base* b2 = &d;
    b.foo(); // Base*
    d.foo(); // Derived*
    b2->foo(); // Base* (1)
    (1) Ce sera, à l’exécution, un Derived*, car b2 est en réalité un Derived, mais à la compilation c’est un Base*. Il n’y a rien que le compilateur puisse faire pour changer cela, et pour cause, cette information n’est pas connue à la compilation.

  3. #23
    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
    Citation Envoyé par Lolilolight Voir le message
    Non je veux pas utiliser boost::any car je suis obligé de connaitre le type en compilation pour le any_cast.
    C'est un peu le principe du langage compilé, d'être connu à la compilation.
    Faudrait te rendre compte que ce que tu espères faire est impossible. Ton approche est mauvaise et n'aboutira à rien.
    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.

  4. #24
    Invité
    Invité(e)
    Par défaut
    Ok je ne vois plus que 2 solutions alors : soit je passe par un système d'introspection et une factory, ou bien je change de language et j'utilise un language interprété.

    Ou bien encore, j'utilise un méta-compiler qui garde également le type réel de l'objet polymorphic à la compilation.

    Mmmm, il faut encore que je réfléchisse pour savoir ce qui serait le mieux.

  5. #25
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Certainement pas le méta compilateur.

    éventuellement, regarde du coté de l'implémentation de LUA pour savoir comment ils font pour permettre du code externe.
    Je ne pense pas que tu sois tout seul avec ta problématique technique.

    Comme j'ai déjà du te le dire dans l'un des sujets liés, si ton problème technique semble insoluble, c'est qu'il l'est probablement.
    Mais c'est sûrement aussi parce que ce n'est pas la bonne solution technique à ton problème logique.

    Regarde ton problème du point de vue extérieur.
    Qu'espères-tu résoudre avec ton tuple dynamique?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Le seul truc que tu peux faire avec un tuple dynamique ça serait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    auto e = ton_tuple_dynamique.at<T>(i); // Lance une exception si T n'est pas le vrai type de e (et si i est invalide)

  7. #27
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Et encore, auto serait compilé en T.
    ça n'est pas dynamique, c'est "décidé à la compilation", plutôt qu'à l'écriture du code source.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    On est d'accord. auto est la même chose que T.

    L'aspect dynamique est le suivant :
    - la taille du tuple peut varier
    - le type d'un élément peut varier (comme dans Boost::any)

    L'aspect statique (à la compilation) est le suivant :
    - lorsque l'utilisateur demande un élément, il doit fournir son type (si incorrect, il aura une exception)

  9. #29
    Invité
    Invité(e)
    Par défaut
    Re salut.
    J'ai revu ma conception en utilisant le pattern factory :

    http://come-david.developpez.com/tut...?page=Fabrique

    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
     
    namespace odfaeg {
    class Serializable {
        public :
        Serializable() {}
        template <typename D>
        Serializable(D* type) {
            Factory<Serializable>::Register(typeid(type).name(), type);
        }
        virtual Serializable* Clone() {
            return new Serializable(*this);
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            std::cout<<"serialize : "<<std::endl;
        }
        std::string type_name;
        static Factory<Serializable> typelist;
    };
    }

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void operator<<(Serializable& serializable) {
        auto object = serializable.typelist.Create(serializable.type_name);
        save(object);
    }


    Mais même problème :

    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
     
    class Base : public odfaeg::Serializable {
    public :
        Base () {}
        Base(std::string name) : odfaeg::Serializable(this) {
            this->name = name;
        }
        std::string getName() {
            return name;
        }
        Base* Clone() {
            return new Base(*this);
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            ar & name;
        }
    private :
        std::string name;
    };
    int main(int argc, char* args[])
    {  
        Base b("A base object");
        std::ofstream file("FichierDeSerialisation");
        odfaeg::OTextArchive oa(file);
        oa<<b;
        return 0;  
    }

    Il m'appelle la fonction serialize de la classe serializable et non pas celle de la classe base.

    Si aucun des designs pattern ne fonctionne. (car le type réel de l'objet est perdu en compilation et donc il doit toujours être connu en compilation pour pouvoir être récupéré)

    Je pense que la seule solution c'est LUA.

    Je sais que il y a boost qui à un mécanisme similaire pour enregistrer les types dans l'archive et instancier le bon type (c'est à dire pas l'objet de la classe de base mais celui de la classe dérivée) mais je sais pas comment ça fonctionne personnellement. (Et le code de boost est une "usine à gaz" pour quelqu'un comme moi.)

  10. #30
    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
    Instancier le bon type n'est pas très compliqué, c'est l'histoire d'un tableau associatif.

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <memory>
    #include <stdexcept>
    #include <unordered_map>
    #include <boost/any.hpp>
     
    //template<class... Ts>
    class Archive
    {
      struct SerializerBase
      {
        std::string name;
     
        SerializerBase(std::string name)
        : name(std::move(name))
        {}
     
        virtual ~SerializerBase()
        {}
     
        virtual boost::any extract(std::istream & is) = 0;
      };
     
      template<class T>
      struct Serializer : SerializerBase
      {
        Serializer()
        : SerializerBase(typeid(T).name())
        {}
     
        boost::any extract(std::istream & is)
        {
          T x;
          is >> x;
          return boost::any(x);
        }
      };
     
      std::unordered_map<std::string, std::unique_ptr<SerializerBase>> serializer;
     
      template<class T>
      static std::string get_name()
      {
        return typeid(T).name();
      }
     
    public:
      template<class T>
      void push()
      {
        serializer.insert(decltype(serializer)::value_type(
          get_name<T>(), decltype(serializer)::mapped_type(new Serializer<T>)));
      }
     
      template<class T>
      void serialize(std::ostream & os, T const & x) const
      {
        os << get_name<T>() << ' ' << x << '\n';
      }
     
      boost::any deserialize(std::istream & is) const
      {
        std::string s;
        is >> s;
        auto it = serializer.find(s);
        if (it == serializer.end()) {
          throw std::runtime_error("deserializer not found");
        }
        return it->second->extract(is);
      }
    };
     
    int main()
    {
      int n = 1;
      std::string s = "plop";
     
      Archive a;
      a.push<int>();
      a.push<std::string>();
     
      std::stringstream io;
      a.serialize(io, n);
      a.serialize(io, s);
     
      std::cout << "serialize:\n" << io.rdbuf() << "\n";
     
      io.seekg(0);
      int n2 = 0;
      std::string s2;
     
      while (std::istream::sentry(io)) {
        boost::any any = a.deserialize(io);
        if (int * pi = boost::any_cast<int>(&any)) {
          n2 = *pi;
        }
        else if(std::string * ps = boost::any_cast<std::string>(&any)) {
          s2 = std::move(*ps);
        }
        else {
          std::cerr << "no matching: " << any.type().name() << '\n';
        }
      }
     
      std::cout << "deserialize:\n"
        << "n1: " << n2 << '\n'
        << "s1: " << s2 << '\n';
    }

  11. #31
    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
    Il m'appelle la fonction serialize de la classe serializable et non pas celle de la classe base.
    C’est normal, ta méthode serialize n’est pas virtuelle. C’est normal, elle est template. Elle ne peut pas être à la fois template et virtuelle.

    Solution 1:
    Archive n’est plus template mais est une classe de base (en fait tu peux fournir un wrapper léger pour cela, en fait, pour ne pas avoir à modifier tous tes sérialiseurs. Mais je crois avoir déjà suggéré cette solution...)

    Solution 2:
    Serializable est template selon Archive.

    Note : je suis quand même étonné que tu bloques à la sérialisation. En général, la sérialisation est la partie facile. C’est plutôt la désérialisation qui pose problème...

  12. #32
    Invité
    Invité(e)
    Par défaut
    Ho laisse tombé c'est juste moi qui est bête.

    Je pense que le double dispatch peut résoudre mon problème et me permettre de simuler une méthode template virtuelle, cependant, ça bloque à l'exécution :
    Voilà donc en gros, j'appelle deux fois la méthode sérialize, ça dépend du type de l'objet C à l'EXECUTION et du type de l'archive. (si c'est une archive de sérialization ou bien de désérialization)
    Ici et non plus en compilation (car je ne connais pas le type réel d'objet en sérializé en compilation vu que ça peut être n'importe quoi (un vecteur, une map, etc...) :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <typename C>
        void serialize (C& object) {
            std::cout<<"save"<<std::endl;
            void(C::*func)(OTextArchive&) = &C::serialize;
            (object.*func)(*this);
        }
        void operator<<(Serializable& serializable) {
           serialize(serializable);
        }

    La première fois j'appelle l'opérateur << sur l'archive en lui fournissant l'objet à sérializer. (celui-ci hérite du sérializer)
    La fonction sérialize cherche la fonction serialize du sérializeur et l'appelle :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace odfaeg {
    class Serializable {
        public :
        template <typename Archive>
        void serialize(Archive & ar) {
             std::cout<<"serialize"<<std::endl;
             ar.serialize(*this);
        }
    };
    Cette fois-ci j'appelle bien la fonction serialize à l'exécution et je fais bien un cast à l'exécution en déréférençant le pointeur this, donc, cette fois-ci c'est la fonction sérialize de la classe dérivant de sérialize qui devrait être appellée.

    Cependant ça ne marche pas il m'appelle toujours la fonction sérialize du serializeur en boucle, pourquoi est ce que mon objet n'est pas casté en l'objet dérivant du sérializeur comme celà le devrait avec le double dispatch ???
    Ou bien alors c'est le pointeur de fonction qui appelle la mauvaise fonction ...

    Bref je ne comprend pas C devrait être de type Serializable lors du 1ère appel à serialize dans l'archive et de type de l'objet à sérializer lors du deuxième appel, mais ce n'est pas le cas, l'objet ne change pas de type, pourquoi ???

  13. #33
    Invité
    Invité(e)
    Par défaut
    Mmmm ha je crois que j'ai compris pourquoi, en fait c'est parce que à la compilation, C est toujours de type Serializable même si le pointeur this à l'exécution est du type de l'objet dérivé, du coup il appelle toujours sérialize sur le serializeur.

    Je crois que je dois juste donner à autre nom à ma fonction serialize du serializeur.

  14. #34
    Invité
    Invité(e)
    Par défaut
    Mwai non je vais devoir faire hériter OTextArchive et ITextArchive d'une classe de base et faire une méthode virtuelle car avec le template là ça va pas et y'a vraiment pas moyen de faire les deux.

  15. #35
    Invité
    Invité(e)
    Par défaut
    Sinon, j'ai essayé ceci (pour pas devoir rendre la classe de base template :
    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
     
    #ifndef ODFAEG_SERIALIZATION
    #define ODFAEG_SERIALIZATION
    #include "../Core/tuple.h"
    #include <iostream>
    #include "factory.h"
    namespace odfaeg {
    template <typename O>
    class Serializable {
        public :
        Serializable() {
            object = nullptr;
        }
        Serializable(O& object) {
            std::cout<<typeid(object).name()<<std::endl;
            this->object = &object;
        }
        template <typename Archive>
        void serialize (Archive & ar) {
             std::cout<<"serialize"<<std::endl;
             if (object != nullptr) {
                std::cout<<typeid(*object).name()<<std::endl;
                ar.serialize(*object);
             }
        }
        O* object;
    };
    }
    #endif // SERIALIZATION

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     template <typename O>
        void serialize (O& object) {
            object.serialize(*this);
        }
        template <typename O>
        void operator<<(Serializable<O>& serializable) {
            serializable.serialize(*this);
        }

    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
     
     
    #include "myApplication.h"
    #include "odfaeg/Graphics/renderWindow.h"
    #include "glCheck.h"
    #include "odfaeg/Graphics/window.h"
    #include <fstream>
    #include "odfaeg/Core/archive.h"
    #include "odfaeg/Core/serialization.h"
    #include "odfaeg/Core/factory.cpp"
    class Base : virtual public odfaeg::Serializable<Base> {
    public :
        Base(std::string name) : Serializable(*this) {
            this->name = name;
        }
        std::string getName() {
            return name;
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            std::cout<<"serialize base"<<std::endl;
            ar & name;
        }
    private :
        std::string name;
    };
    class DerivedObject : public Base, public odfaeg::Serializable<DerivedObject> {
        public :
        DerivedObject(std::string name) : Serializable<DerivedObject>(*this), Base(name) {
            this->name = name;
        }
        std::string getName() {
            return Base::getName() + "\n" + name;
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            std::cout<<"serialize derived"<<std::endl;
            Base::serialize(ar);
            ar & name;
        }
    private :
        std::string name;
    };
    int main(int argc, char* args[])
    {  
        Base* b = new DerivedObject("A base object");
        std::ofstream file("FichierDeSerialisation");
        odfaeg::OTextArchive oa(file);
        oa<<*b;
        return 0;
    }

    Mais ça ne fonctionne pas, la méthode serialize de la classe archive n'est pas appelée... (juste celle de la classe Serializable l'est)
    (Enfin tout du moins, d'après les cout que j'ai mis)

    Bref j'ai essayé toutes les solutions que je pouvais et aucun ne marche donc je vais devoir faire une classe de base pour toutes les archives.

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

    J'essaye de faire une classe de base pour toute les archives, j'ai pu ainsi enlevé le template et faire en sorte de simuler une fonction template virtuelle.

    Mais je n'arrive pas à faire le wrapper, il me donne une erreur 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
     
    class Archive;
    template <typename D>
    class DerivedArchive : public Archive {
    public :
        DerivedArchive(D* derived) {
        }
        virtual D& warp() {
            return *derived;
        }
    private :
        D* derived;
    };

    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
     
    namespace odfaeg {
    template <typename O>
    class Serializer {
        public :
        Serializer() {
            object = nullptr;
        }
        Serializer(O& object) {
            this->object = &object;
        }
        void serialize(Archive & ar) {
            if (object != nullptr) {
                object.serialize(ar.warp());
            }
        }
        O* object;
    };

    Voici l'erreur que j'ai en compilation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ||=== Build: Debug in ODFAEG (compiler: GNU GCC Compiler) ===|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|18|error: invalid use of incomplete type ‘class odfaeg::Archive’|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|16|error: forward declaration of ‘class odfaeg::Archive’|
    ||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
    Dois je faire une fonction serialize pour chaque type d'archive et un wrapper template comme pour l'exercice ci-dessus ?

    Si oui ça me semble être assez lourd surtout si on a beaucoup de type d'archives différentes.

  17. #37
    Invité
    Invité(e)
    Par défaut
    Une syntaxe déjà plus claire mais ne compile pas :
    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
     
    class Archive {
        virtual Archive& warp() = 0;
    };
     
    template <typename D>
    class DerivedArchive : public D {
    public :
        DerivedArchive(D* derived) {
        }
        virtual D& warp() override {
            return *derived;
        }
    private :
        D* derived;
    };

    Toujours la même erreur :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ||=== Build: Debug in ODFAEG (compiler: GNU GCC Compiler) ===|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h||In instantiation of ‘class odfaeg::DerivedArchive<odfaeg::OTextArchive>’:|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|29|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|19|error: invalid use of incomplete type ‘class odfaeg::OTextArchive’|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|29|error: forward declaration of ‘class odfaeg::OTextArchive’|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|23|error: ‘D& odfaeg::DerivedArchive<D>::warp() [with D = odfaeg::OTextArchive]’ marked override, but does not override|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h||In instantiation of ‘class odfaeg::DerivedArchive<odfaeg::ITextArchive>’:|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|80|required from here|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|19|error: invalid use of incomplete type ‘class odfaeg::ITextArchive’|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|80|error: forward declaration of ‘class odfaeg::ITextArchive’|
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/archive.h|23|error: ‘D& odfaeg::DerivedArchive<D>::warp() [with D = odfaeg::ITextArchive]’ marked override, but does not override|
    ||=== Build failed: 6 error(s), 4 warning(s) (0 minute(s), 0 second(s)) ===|

  18. #38
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    le code d'erreur se réfère à odfaeg::OTextArchive.
    montre nous le code correspondant à cette classe.

    Il te dit que le type est incomplet au moment d'instancier la classe.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  19. #39
    Invité
    Invité(e)
    Par défaut
    e code d'erreur se réfère à odfaeg::OTextArchive.
    montre nous le code correspondant à cette classe.

    Il te dit que le type est incomplet au moment d'instancier la classe.
    Ok le voici :

    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
     
    class OTextArchive : public DerivedArchive<OTextArchive> {
    public :
        OTextArchive(std::ostream& buffer) : DerivedArchive<OTextArchive>(this), buffer(buffer) {
        }
        template <typename T>
        void operator& (T& data) {
            buffer<<data;
        }
        template <typename T>
        void operator& (T* data) {
            std::map<unsigned long long int, unsigned long long int>::iterator it = adresses.find(data);
            if (it != adresses.end()) {
                buffer<<it->second;
            } else {
                std::pair<unsigned long long int, unsigned long long int> newAddress (data, nbSerialized);
                adresses.insert(newAddress);
                buffer<<newAddress.second;
                buffer<<*data;
            }
            nbSerialized++;
        }
        template <typename T>
        void operator& (std::vector<T>& data) {
            std::size_t size = data.size();
            buffer<<size;
            for (unsigned int i = 0; i < data.size(); i++)
                buffer<<data[i];
        }
        template <typename T>
        void operator& (std::vector<T*> data) {
            std::size_t size = data.size();
            buffer<<size;
            for (unsigned int i = 0; i < data.size(); i++)
                buffer<<data[i];
        }
        template <typename O>
        void operator<<(Serializer<O>& serializable) {
            serializable.serialize(*this);
        }
        template <typename O>
        void operator<<(Serializer<O>* serializable) {
            serializable->serialize(*this);
        }
        OTextArchive& get() {
            return *this;
        }
    private :
        std::ostream& buffer;
        std::map<unsigned long long int, unsigned long long int> adresses;
        static unsigned long long int nbSerialized;
    };

  20. #40
    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
    C’est un problème d’inclusion.

    Pour overrider une classe, il faut en connaître la définition. Là, ton compilateur n’en connaît que la déclaration, d’où l’erreur :

    error: invalid use of incomplete type ‘class odfaeg::OTextArchive’|
    La solution, c’est qu’il te faut le #include qui va bien (probablement #include "otextarchive.h" ) dans ce fichier.

    S’il y ait déjà, c’est probablement qu’il y a un #include "derivedarchive.h" dant otextarchive.h (ou un des fichiers qu’il inclut), et donc que tu as un problème de dépendances cycliques.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 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