c++boostboost-serialization

Can boost::container::strings be serialized using boost serialization?


I am attempting to serialize a class which contains a boost::container::string

#include <iostream>
#include <cstdlib>
#include <boost/container/string.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>

class car
{
public:
    car() {}
    car(boost::container::string make) : make(make) {}
    boost::container::string make;

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & make;
    }
};

int main()
{
    car my_car("ford");

    std::stringstream ss;
    boost::archive::text_oarchive oa(ss);
    oa << my_car;
    
    car new_car;
    boost::archive::text_iarchive ia(ss);
    ia >> new_car;    
}

But the above fails to compile with the following error:

boost/serialization/access.hpp:116:11: error: 'class boost::container::basic_string<char>' has no member named 'serialize'

The same code can be changed to use std::string and it compiles fine.

Can boost::container::strings be serialized and if so what am I doing incorrectly or missing?


Solution

  • CAUTION

    It turns out that (at least today) this answer is broken. See Boost serialize for std::basic_string with custom allocator for a better solution that works in Boost 1.83.0

    Yes. Surprisingly, the necessary support is not baked into Boost. Though if you look inside the string serialization header you will find that it has support as "primitive", and it takes just one line to enable it:

    BOOST_CLASS_IMPLEMENTATION(boost::container::string, boost::serialization::primitive_type)
    

    Now it works the same as std::string:

    Live On Coliru

    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/container/string.hpp>
    #include <iostream>
    
    BOOST_CLASS_IMPLEMENTATION(boost::container::string, boost::serialization::primitive_type)
    
    struct car {
        template<class Ar> void serialize(Ar& ar, unsigned) { ar & make; }
        boost::container::string make;
    };
    
    int main() {
        std::stringstream ss;
        {
            boost::archive::text_oarchive oa(ss);
            car my_car{"ford"};
            oa << my_car;
        } // close archive
    
        std::cout << ss.str() << "\n";
        
        boost::archive::text_iarchive ia(ss);
        car new_car;
        ia >> new_car;    
    }
    

    Prints

    22 serialization::archive 17 0 0 ford