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 :

Enchainement des opérateurs >> sur les objets ostream. (Problème) (lvalue to rvalue)


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Enchainement des opérateurs >> sur les objets ostream. (Problème) (lvalue to rvalue)
    Salut, j'essaye de mettre au point un système de sérialization à l'aide des opérateurs << et >>, le principe est simple, je déclare un objet de type ofstram (ou bien istream) et je le passe à une archive qui se charge de sérailizer tout les types de données.

    Chaque classe hérite d'une classe de base Serializer et le but est d'appeler les opérateur << ou bien >> sur un type de base (int, string, std::vector, pointeurs, etc...) ou bien sur un objet qui hérite du serializer dans le but de pouvoir chaîner les opérateur sur tout les types de donnée un peu 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
    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
     
    template<typename O>
    class Serializer;
    class OTextArchive {
    public :
        OTextArchive(std::ostream& buffer) : 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 save (O* object, void(O::*func)(OTextArchive&)) {
            (object->*func)(*this);
        }
        template <typename B, typename D>
        void save (B* base, void(D::*func)(OTextArchive&)) {
            (static_cast<D*>(base)->*func)(*this);
        }
        template <typename C>
        void operator<<(Serializer<C>* serializer) {
            void(C::*func)(OTextArchive&);
            serializer->getSerializeFunc(&func);
            C* object = static_cast<C*>(serializer);
            save(object, func);
            serializer->onSave();
        }
        template <typename C>
        void operator<<(Serializer<C>& serializer) {
            void(C::*func)(OTextArchive&);
            serializer.getSerializeFunc(&func);
            C* object = static_cast<C*>(&serializer);
            save(object, func);
            serializer.onSave();
        }
    private :
        std::ostream& buffer;
        std::map<unsigned long long int, unsigned long long int> adresses;
        static unsigned long long int nbSerialized;
    };

    Le serializer contient juste la fonction à appeler qui défini comment sérializer mes objets dans les archives à l'aide de l'opérateur&, exactement comme le fait boost. (Le template correspond au type de l'objet à sérializer)

    Bref quand je veux sérializer un object qui hérite de sérializer pas de problème, par contre, quand je veux sérializer un objet qui contient un objet qui hérite du sérializer et que je veux chainer les opérateur << et >>, là, le compilateur me ressort une 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
    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
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/local/include/odfaeg/Core/archive.h||In instantiation of ‘void odfaeg::OTextArchive::operator&(T&&) [with T = odfaeg::Image&]’:|
    /usr/local/include/odfaeg/Graphics/texture.h|474|required from ‘void odfaeg::Texture::serialize(Archive&) [with Archive = odfaeg::OTextArchive]’|
    /usr/local/include/odfaeg/Core/serialization.h|12|required from ‘void odfaeg::Serializer<O>::getSerializeFunc(void (O::**)(A&)) [with A = odfaeg::OTextArchive; O = odfaeg::Texture]’|
    /usr/local/include/odfaeg/Core/archive.h|67|required from ‘void odfaeg::OTextArchive::operator<<(odfaeg::Serializer<C>&) [with C = odfaeg::Texture]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|21|required from here|
    /usr/local/include/odfaeg/Core/archive.h|19|error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’|
    /usr/include/c++/4.8/ostream|602|error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = odfaeg::Image]’|
    /usr/local/include/odfaeg/Core/archive.h||In instantiation of ‘void odfaeg::ITextArchive::operator&(T&&) [with T = odfaeg::Image&]’:|
    /usr/local/include/odfaeg/Graphics/texture.h|474|required from ‘void odfaeg::Texture::serialize(Archive&) [with Archive = odfaeg::ITextArchive]’|
    /usr/local/include/odfaeg/Core/serialization.h|12|required from ‘void odfaeg::Serializer<O>::getSerializeFunc(void (O::**)(A&)) [with A = odfaeg::ITextArchive; O = odfaeg::Texture]’|
    /usr/local/include/odfaeg/Core/archive.h|136|required from ‘void odfaeg::ITextArchive::operator>>(odfaeg::Serializer<C>&) [with C = odfaeg::Texture]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|27|required from here|
    /usr/local/include/odfaeg/Core/archive.h|83|error: cannot bind ‘std::istream {aka std::basic_istream<char>}’ lvalue to ‘std::basic_istream<char>&&’|
    /usr/include/c++/4.8/istream|872|error:   initializing argument 1 of ‘std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&&, _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = odfaeg::Image]’|
    /usr/include/boost/serialization/access.hpp||In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive; T = std::vector<odfaeg::g2d::Entity*>]’:|
    /usr/local/include/boost/serialization/serialization.hpp|69|required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/serialization/serialization.hpp|128|required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/iserializer.hpp|192|required from ‘void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/iserializer.hpp|120|required from ‘class boost::archive::detail::iserializer<boost::archive::text_iarchive, std::vector<odfaeg::g2d::Entity*> >’|
    /usr/local/include/boost/archive/detail/iserializer.hpp|387|  [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]|
    /usr/local/include/boost/archive/detail/iserializer.hpp|592|required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::text_iarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/common_iarchive.hpp|66|required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_iarchive]’|
    /usr/local/include/boost/archive/basic_text_iarchive.hpp|65|required from ‘void boost::archive::basic_text_iarchive<Archive>::load_override(T&, int) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_iarchive]’|
    /usr/local/include/odfaeg/Core/boost/archive/text_iarchive.hpp|82|required from ‘void boost::archive::text_iarchive_impl<Archive>::load_override(T&, int) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_iarchive]’|
    /usr/local/include/boost/archive/detail/interface_iarchive.hpp|60|required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_iarchive]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/myApplication.h|217|required from here|
    /usr/include/boost/serialization/access.hpp|118|error: ‘class std::vector<odfaeg::g2d::Entity*>’ has no member named ‘serialize’|
    /usr/include/boost/serialization/access.hpp||In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = std::vector<odfaeg::g2d::Entity*>]’:|
    /usr/local/include/boost/serialization/serialization.hpp|69|required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/serialization/serialization.hpp|128|required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/oserializer.hpp|152|required from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/oserializer.hpp|101|required from ‘class boost::archive::detail::oserializer<boost::archive::text_oarchive, std::vector<odfaeg::g2d::Entity*> >’|
    /usr/local/include/boost/archive/detail/oserializer.hpp|253|  [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]|
    /usr/local/include/boost/archive/detail/oserializer.hpp|314|required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_oarchive]’|
    /usr/local/include/boost/archive/detail/oserializer.hpp|525|required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::text_oarchive; T = std::vector<odfaeg::g2d::Entity*>]’|
    /usr/local/include/boost/archive/detail/common_oarchive.hpp|69|required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_oarchive]’|
    /usr/local/include/boost/archive/basic_text_oarchive.hpp|80|required from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_oarchive]’|
    /usr/local/include/boost/archive/detail/interface_oarchive.hpp|63|required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = std::vector<odfaeg::g2d::Entity*>; Archive = boost::archive::text_oarchive]’|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/myApplication.h|420|required from here|
    /usr/include/boost/serialization/access.hpp|118|error: ‘class std::vector<odfaeg::g2d::Entity*>’ has no member named ‘serialize’|
    ||=== Build failed: 8 error(s), 32 warning(s) (0 minute(s), 3 second(s)) ===|

    L'erreur est à cette ligne :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <typename T>
    void operator& (T& data) {
        buffer<<data;
    }

    buffer est u objet de type ostream et T un objet qui hérite du sérializer.

    Pourquoi il me met deux && devant l'objet ostream et comment en retirer un ?

  2. #2
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    Ça serait bien d'avoir un code minimal, complet, compilable qui reproduit le pb, car pour le moment il manque la définition de Serializer et son utilisation (qui hérite de quoi ? comment est utilisé OTextArchive ? pas clair).

  3. #3
    Invité
    Invité(e)
    Par défaut
    J'ai trouvé le problème en fait il fallait aussi redéfinir les operateurs << et >> dans le sérializer :

    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
     
    #ifndef ODFAEG_SERIALIZATION
    #define ODFAEG_SERIALIZATION
    #include "archive.h"
    #include <iostream>
     
    namespace odfaeg {
    template <class O>
    class Serializer {
        public :
        Serializer(O* object) {
        }
        template <typename A>
        void getSerializeFunc(void(O::**func)(A&)) {
             *func = &O::serialize;
        }
        virtual void onSave() {
        }
        virtual void onLoad() {
        }
        friend std::ostream& operator<< (std::ostream &out,
                                       const O& object) {
            out<<object;
            return out;
        }
        friend std::istream& operator>> (std::istream &in,
                                       O& object) {
            in>>object;
            return in;
        }
        private :
        O* object;
    };
    }
    #endif // SERIALIZATION

    Pour qu'il puisse déduire le type du template dans le cas de la composition. (C'est à dire une classe qui hérite de Serializer<Texture> par exemple et qui contient un objet de type Serializer<Image>

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/09/2009, 08h30
  2. Mettre des textures et des couleurs sur les objets
    Par MaTtaW dans le forum PhysX et APEX
    Réponses: 5
    Dernier message: 31/07/2009, 17h42
  3. Réponses: 7
    Dernier message: 09/04/2009, 09h34
  4. Réponses: 8
    Dernier message: 12/07/2008, 12h29
  5. Ajouter des properties sur les objets handle
    Par lince102 dans le forum Interfaces Graphiques
    Réponses: 10
    Dernier message: 12/12/2007, 10h31

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