Search code examples
c++c++11serializationboost

boost serialization vector in c++


Hello so i have this two classes and i want to serialize the vector

class PlayerInventory
{
private:
    friend class boost::serialization::access;
    template <class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar &itemID &itemCount;
    }

public:
    int itemID;
    int itemCount;
};

class player
{
private:
    friend class boost::serialization::access;
    template <class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar &username &password &inv;
    }

public:
    string username;
    string password;
    std::vector<PlayerInventory> inv;
};

for some reason its not serializing the full vector just first 2 elements is this the correct way of doing it ?


Solution

  • My strongest suspicion is that you might not fully flush the archive stream before reading.

    Simple proof of concept, note the comment:

    Live On Coliru

    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/vector.hpp>
    #include <iostream>
    #include <iomanip>
    
    class PlayerInventory {
        friend class boost::serialization::access;
        template <class Archive> void serialize(Archive& ar, unsigned) {
            ar &itemID &itemCount;
        }
    
      public:
        int itemID;
        int itemCount;
    };
    
    class player {
        friend class boost::serialization::access;
        template <class Archive> void serialize(Archive& ar, unsigned) {
            ar &username &password &inv;
        }
    
      public:
        std::string                  username;
        std::string                  password;
        std::vector<PlayerInventory> inv;
    };
    
    #include <sstream>
    int main() {
        std::stringstream ss;
    
        {
            boost::archive::text_oarchive oa(ss);
    
            player to_save;
            to_save.username = "bla";
            to_save.password = "blo";
            to_save.inv = {
                    { 1, 17 },
                    { 2, 11 },
                    { 3, 8800 },
                    { 4, 0 },
                    { 5, 1 },
                    { 6, 1 },
                    { 7, 1 },
                    { 8, 1 },
                    { 9, 42 },
                };
    
            oa << to_save;
        } // <-- destructor of text_oarchive
    
        std::cout << "Serialized stream: " << std::quoted(ss.str()) << std::endl;
    
        player loaded;
        {
            boost::archive::text_iarchive ia(ss);
            ia >> loaded;
        }
    
        std::cout << "Roundtrip username:" << std::quoted(loaded.username)
                  << " password:" << std::quoted(loaded.password) << std::endl;
    
        for (auto [id, count] : loaded.inv) {
            std::cout << " - item " << id << " count:" << count << std::endl;
        }
    }
    

    Prints

    Serialized stream: "22 serialization::archive 17 0 0 3 bla 3 blo 0 0 9 0 0 0 1 17 2 11 3 8800 4 0 5 1 6 1 7 1 8 1 9 42
    "
    Roundtrip username:"bla" password:"blo"
     - item 1 count:17
     - item 2 count:11
     - item 3 count:8800
     - item 4 count:0
     - item 5 count:1
     - item 6 count:1
     - item 7 count:1
     - item 8 count:1
     - item 9 count:42