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 ?