Reputation: 594
I'm trying to create a serialize function within my class, called location, and send it after serializing. I can't figure out why I'm getting an error, but maybe it's because I'm trying to serialize a string*.
Here's a minimal example
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/serialization.hpp>
struct WithPointers {
WithPointers(const char* of = nullptr, const char* n = nullptr) {
if (n) name = new std::string(n);
}
WithPointers(WithPointers const&) = delete;
WithPointers& operator=(WithPointers const&) = delete;
~WithPointers() {
delete name;
}
std::string* name = nullptr;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & name;
}
};
struct WithoutPointers {
WithoutPointers(const char* of = nullptr, const char* n = nullptr) {
if (n) name = n;
}
std::string name;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & name;
}
};
#include <iostream>
#include <sstream>
int main()
{
std::string serialized;
typedef WithoutPointers Location; // DOESN'T COMPILE
//typedef WithPointers Location; // COMPILES
{
Location l1("da location", "da name");
std::ostringstream oss;
boost::archive::text_oarchive oa(oss);
oa << l1;
serialized = oss.str();
}
std::cout << "serialized: '" << serialized << "'\n";
}
It works if we use WithoutPointers
Upvotes: 2
Views: 3643
Reputation: 392833
To be fair, I don't see a reason why this wouldn't work. It appears to me to be a kind of aribitrary limitation, potentially even a bug.
To contrast, here's a version that simply wraps the std::string
:
struct XString {
std::string s;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & s;
}
};
Interestingly, using this everything works as expected:
struct WithPointers {
WithPointers(const char* n = nullptr) {
if (n) name = new XString ({ n });
}
WithPointers(WithPointers const&) = delete;
WithPointers& operator=(WithPointers const&) = delete;
~WithPointers() {
delete name;
}
XString* name = nullptr;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & name;
}
};
See it Live On Coliru
Prints:
serialized: '22 serialization::archive 11 0 0 1 1 0
0 7 da name'
Deserialized as 'da name'
I'd still advise against using the raw std::string*
. Other than that you should probably mention this problem on the Boost mailing lists
For reference:
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/serialization.hpp>
struct XString {
std::string s;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & s;
}
};
struct WithPointers {
WithPointers(const char* n = nullptr) {
if (n) name = new XString ({ n });
}
WithPointers(WithPointers const&) = delete;
WithPointers& operator=(WithPointers const&) = delete;
~WithPointers() {
delete name;
}
XString* name = nullptr;
template <class Archive>
void serialize(Archive &ar, unsigned int) {
ar & name;
}
};
#include <iostream>
#include <sstream>
int main()
{
std::string serialized;
typedef WithPointers Location;
{
Location l1("da name");
std::ostringstream oss;
boost::archive::text_oarchive oa(oss);
oa << l1;
serialized = oss.str();
}
std::cout << "serialized: '" << serialized << "'\n";
{
Location l2;
std::istringstream iss(serialized);
boost::archive::text_iarchive ia(iss);
ia >> l2;
std::cout << "Deserialized as '" << l2.name->s << "'\n";
}
}
Upvotes: 1