Boost序列化带自定义分配器的std::basic_string:问题与优化咨询
Boost序列化自定义字符串类型的问题与优化需求
自定义字符串类型定义如下:
using CustomString = std::basic_string<char, std::char_traits<char>, CustomAllocator<char>>;
1. 标记为primitive_type的问题
由于该类型除分配器外与std::string定义完全一致,最初采用Boost序列化std::string的方式,在using语句后添加:
BOOST_CLASS_IMPLEMENTATION(CustomString, boost::serialization::primitive_type)
此方法在序列化无空格字符串时正常,但序列化含空格的字符串(如"Hello World")时,反序列化只能读取到第一个空格前的内容(如"Hello")。原因是Boost对std::string会先写入长度字段,而自定义字符串未执行该逻辑,Boost相关源码实现如下:
text_oarchive_impl<Archive>::save(const std::string &s) { const std::size_t size = s.size(); *this->This() << size; this->This()->newtoken(); os << s; }
Stack Overflow上的相关问题也存在同样情况,示例可复现该问题。
2. 自定义序列化函数的冗余问题
随后自行编写了序列化函数:
namespace boost { namespace serialization { template<class Archive> inline void serialize(Archive& ar, CustomString & s, const unsigned int file_version) { boost::serialization::split_free(ar, s, file_version); } template<typename Archive> inline void save( Archive& ar, const CustomString & s, const unsigned int /* file_version */ ) { ar << s.size(); for (size_t i = 0; i < s.size(); i++) { ar << s.c_str()[i]; } } template<typename Archive> inline void load( Archive& ar, CustomString & s, const unsigned int /* file_version */ ) { size_t size; ar >> size; char c; for (size_t i=0; i < size;i++) { ar >> c; s.push_back(c); } } } // namespace serialization } // namespace boost
该代码可正常运行,但生成的归档文件过长,因为每个字符被编码为十进制值:
std::string归档内容:22 serialization::archive 19 11 Hello WorldCustomString归档内容:22 serialization::archive 19 0 0 11 72 101 108 108 111 32 87 111 114 108 100
希望能得到优化上述两种实现方法的建议。
内容的提问来源于stack exchange,提问作者johesi
相关产品推荐
相关产品推荐

