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

Boost C++ Discussion :

xml_iarchive cassé pour les classes template ?


Sujet :

Boost C++

  1. #1
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut xml_iarchive cassé pour les classes template ?
    Salut,

    Je suis occupé à tester la sérialization avec boost sur des classes templates...

    Je pars donc d'une classe du genre 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
    20
    21
    22
    23
    24
    template <typename Value, int>
    struct FARFELUE_API TPoint;
    template <typename Value>
    struct FARFELUE_API TPoint<Value, 2>
    {
        typedef Value value_type;
        typedef TPoint<value_type, 2> point_type;
        TPoint()  = default;
        TPoint(value_type x, value_type y):x(x),y(y){}
        value_type x;
        value_type y;
    };
     
    template <typename Value>
    struct FARFELUE_API TPoint<Value, 3>
    {
        typedef Value value_type;
        typedef TPoint<value_type, 3> point_type;
        TPoint()  = default;
        TPoint(value_type x, value_type y, value_type z):x(x),y(y),z(z){}
        value_type x;
        value_type y;
        value_type z;
    };
    avec un code de sérialization non intrusif 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
    20
    21
    22
    23
    namespace boost
    {
        namespace serialization
        {
            template<typename Archive, typename T>
            void serialize( Archive & ar, TPoint<T,2> & pt, 
                            const unsigned int version)
            {
                ar & BOOST_SERIALIZATION_NVP(pt.x)
                   & BOOST_SERIALIZATION_NVP(pt.y);
            }
            template<typename Archive, typename T>
            void serialize( Archive & ar, TPoint<T,3> & pt, 
                         const unsigned int version)
            {
                ar & BOOST_SERIALIZATION_NVP(pt.x)
                   & BOOST_SERIALIZATION_NVP(pt.y)
                   & BOOST_SERIALIZATION_NVP(pt.z);
            }
        }
    }
    typedef boost::archive::text_oarchive output_file; /* (1) */
    typedef boost::archive::text_iarchive output_file; /* (1) */
    (1) Tant que je travaile avec des couples boost::archive::text_oarchive / boost::archive::text_iarchive ou boost::archive::binary_oarchive / boost::archive::binary_iarchive, sous réserve d'adapter les inclusion d'en-tete de boost::archive, un code 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
    20
    21
    22
    23
    24
    25
    26
    void save(TPoint<int, 2> const & point)
    {
        std::cout << "before save " <<std::endl
                  <<point.x << " " << point.y<<std::endl;
        std::ofstream ofs("point.xml");
        assert(ofs.good());
        output_file of(ofs);
        of << point;
    }
    void load(TPoint<int, 2> & point)
    {
        std::ifstream ifs("point.xml");
        assert(ifs.good());
        input_file ia(ifs);
        ia >> point;
        std::cout << "after reading " <<std::endl
                  <<point.x << " " << point.y<<std::endl;
    }
    int main()
    {
        TPoint<int , 2> point(0,4);
        save(point);
        TPoint<int , 2>  loaded;
        load(loaded);
        return 0;
    }
    compile et fonctionne parfaitement.

    Par contre, dés que j'essaye de travailler avec des archive xml, j'obtiens l'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ..\..\boostMinGW\include\boost-1_47\boost\archive\basic_xml_iarchive.hpp||In member function 'void boost::archive::basic_xml_iarchive<Archive>::load_override(T&, int) [with T = TPoint<int, 2>, Archive = boost::archive::xml_iarchive]':|
    ..\..\boostMinGW\include\boost-1_47\boost\archive\xml_iarchive.hpp:93|9|instantiated from 'void boost::archive::xml_iarchive_impl<Archive>::load_override(T&, int) [with T = TPoint<int, 2>, Archive = boost::archive::xml_iarchive]'|
    ..\..\boostMinGW\include\boost-1_47\boost\archive\detail\interface_iarchive.hpp:60|9|instantiated from 'Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = TPoint<int, 2>, Archive = boost::archive::xml_iarchive]'|
    C:\projects\farfelue\test\main.cpp:39|11|instantiated from here|
    ..\..\boostMinGW\include\boost-1_47\boost\archive\basic_xml_iarchive.hpp|70|error: no matching function for call to 'assertion_failed(mpl_::failed************ boost::serialization::is_wrapper<TPoint<int, 2> >::************)'|
    ||=== Build finished: 1 errors, 0 warnings (0 minutes, 1 seconds) ===|
    et ce, uniquement si j'essaye de décommenter la fonction "load"...

    Le plus bizard de l'histoire, c'est que, pour autant que le contenu de la fonction load soit commentée, la compilation s'effectue correctement (ca, c'est normal ) mais que le fichier généré par save semble être tout à fait correct...

    • Aurais-je raté quelque chose
    • Devrais-je veiller à créer une spécialisation de is_wrapper
    • Est-ce, simplement, un bug de boost
    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

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Les macros pour définir les nvp doivent être utilisé dans le même namespace que la classe.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Goten Voir le message
    Les macros pour définir les nvp doivent être utilisé dans le même namespace que la classe.
    Si tu le dis...

    Le problème est que, si j'essaye d'utiliser la version intrusive, ce qui a d'office pour effet que BOOST_SERIALIZATION_NVP soit utilisé dans le même espace de noms que la classe, j'obtiens quand même la même erreur...

    Et que, si je commente la ligne qui pose problème dans xml_iarchive.hpp (à savoir
    BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
    ) je me tape une exception lors de la lecture

    Ceci dit, en regardant les fichiers générés d'un peu plus près, j'aurais tendance à dire qu'ils sont pour le moins mal formé, certaines balises ouvertes n'étant pas fermées
    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

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void save(TPoint<int, 2> const & point)
    {
        std::cout << "before save " <<std::endl
                  <<point.x << " " << point.y<<std::endl;
        std::ofstream ofs("point.xml");
        assert(ofs.good());
        output_file of(ofs);
        of << point;
    }
    Même traitement que pour les autres données, faut lui donner un nom à ton point aussi :

    of << BOOST_SERIALIZATION_NVP(point);

    la même dans l'autre sens.


    Si tu le dis...
    http://www.boost.org/doc/libs/1_47_0...doc/index.html

    Note that these macros must be used in the namespace of the class, and without qualifying the namespace in the argument.
    et si tu veux le faire en dehors utilise boost::serialization::make_nvp
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Oui, effectivement, je suis un imbécile...

    j'avais correctement mis BOOST_SERIALIZATION_NVP partout sauf... dans les fonctions load et save

    Je m'en suis rendu compte juste avant de voire ta réponse

    Bref, voilà, une discussion pour rien

    Merci de ton aide
    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

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 24/06/2009, 10h37
  2. les classes templates
    Par dot-_-net dans le forum C++
    Réponses: 5
    Dernier message: 17/01/2009, 10h37
  3. Définition de méthodes pour une classe template
    Par Pragmateek dans le forum Langage
    Réponses: 13
    Dernier message: 20/12/2008, 00h46
  4. [osCommerce] Quel nom pour les classes de mysql ?
    Par Xvega dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 14/10/2008, 21h29
  5. Exercice: Aide pour les classes
    Par benben10 dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 17/07/2008, 15h36

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