Cereal library--从Boost到Cereal的过渡
来源:互联网 发布:我知主掌握明天歌谱 编辑:程序博客网 时间:2024/05/16 11:18
原文翻译自:
http://uscilab.github.io/cereal/transition_from_boost.html
如果你曾经使用过Boost序列化功能,你会发现Cereal和Boost很相似。这是因为Cereal被设计时就考虑了Boost用户的使用习惯,模仿了许多Boost序列化库的语法习惯。本文是一个简要的过渡指南。请保证你已经能正常安装Cereal,并且对基本语法有一个简要的认识,可参考文章“Cereal快速入门”。
TLDR版本(TLDR??)
Cereal和Boost序列库的接口非常相似,在一些情况下可以非常迅速的将Boost库替换成Cereal。但是即便如此,Cereal和Boost还是有很大的区别的,想要了解更多继续阅读本文或者参考
http://uscilab.github.io/cereal/assets/doxygen/index.html。
差异
- Cereal在序列化时只存储非常少量的元数据(metadata)。反之Boost序列化库存储了大量的元数据,例如Boost库版本等等。Cereal则并不需要版本信息来保证序列化和反序列化时库版本一致。
- Cereal只需要头文件即可,不再需要其他依赖库。在使用Boost时,由于Boost库繁多复杂,一个非常头疼的问题是如何保证不同机器间的Boost版本一致。但是这个问题在使用Cereal时并不存在,因为Cereal非常容易安装和使用。
- Cereal基本支持所有的标准库。并且一些Cereal支持的标准,Boost并不支持,这包括:forward_list、memory、queue、stack、tuple、unordered_set和unordered_map。
- Cereal不支持指针,并且需要支持C++11的编译器。但是从一个使用者的角度来看,Cereal的代码是非常简单理解和扩展的。
- 相比Boost,Cereal更加简洁。例如,在Cereal中当把serialize函数分成load/save函数时,不需要提前使用宏声明。Cereal还使用了static_assert,提供了更加准确的错误提示。
- Cereal和Boost使用了不同的语法规则进行序列化。Boost使用的是&,<<和>>,而在Cereal中使用的是(),例如archive(myData1,myData2)。但是为了方便,Cereal也支持Boost的语法规则。总而言之Cereal和Boost非常相似,但是读者在使用时还说要根据情况认真阅读doxygen文档以分辨其中的细小差异。
过渡的例子
要将Boost修改成Cereal,并不需要对代码进行大量修改。前文中已经提到,Cereal支持Boost的语法规则。下文中给出一个例子,示例如何从Boost转移到Cereal中。
#include <boost/archive/binary_oarchive.hpp>#include <cereal/archives/binary.hpp>#include <fstream>class SomeData{ public: SomeData() = default; int a; int b; private: friend class cereal::access; // 友函数,获取版本信息 boost::serialization::access; // 可选项,Cereal支持版本信息 // // 注意第二个参数从const unigned int改成了const std::uint32_t template <class Archive> void save( Archive & ar, std::uint32_t const version ) const { // Cereal支持Boost语法 ar << a << b; } template <class Archive> void load( Archive & ar, std::uint32_t const version ) { ar >> a; ar >> b; } // Cereal并不需要此处声明 BOOST_SERIALIZATION_SPLIT_MEMBER()};//当使用Cereal时,由于BOOST_SERIALIZATION_SPLIT_MEMBER由于声明了一个serialize函数,会使得Cereal产生一个错误。Cereal不能同时支持load/save和serialize。// 为解决此问题,需要临时使用一个特殊函数来保证Cereal不把Boost的宏当做错误。当你把这个宏删掉后,这个特殊函数也就没有必要再使用了。CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( SomeData, cereal::specialization::member_load_save )BOOST_CLASS_VERSION(SomeData, 1);CEREAL_CLASS_VERSION(SomeData, 1); struct MyType{ int x; double y; SomeData s; template <class Archive> void serialize( Archive & ar, std::uint32_t const version ) { ar & x & y; // 在Cereal中&是合法的,但并不推荐 ar & s; }};int main(){ std::ofstream os("out.bin", std::ios::binary); // using boost { boost::archive::binary_oarchive ar(os); MyType m; ar << m; // Cereal支持Boost的语法 } // using cereal { cereal::BinaryOutputArchive ar(os); MyType m; ar << m; } return 0;}
在上述代码中,仅仅通过添加一个Cereal版本友函数,就能将Boost快速过渡到Cereal。但是当你使用Boost中的其他特性时,可能需要修改其他代码,不再赘述。
观察代码不难发现,在Boost使用load/save模式序列化,需要使用宏BOOST_MEMBER_SPLIT。但是Cereal则更人性化,直接使用即可。
不能将boost::serialization::access设置为友函数,应该将cereal::access设置为友函数,详情参照cereal/access.hpp。
在Cereal,类版本信息是一个额外信息,不是必要信息,因此在serialization函数通常将其作为第二个参数,格式为std::uint32_t const。除此之外,宏BOOST_CLASS_VERSION 在Cereal中有一个对应宏CEREAL_CLASS_VERSION。
总结,Cereal和Boost有非常多的相似之处,但是也略有差异。因此特别建议在使用时详细阅读doxygen文档。
下文把上文重写,改成了完全的Cereal格式:
#include <cereal/archives/binary.hpp>#include <fstream>class SomeData{ public: SomeData() = default; int a; int b; private: friend class cereal::access; // 版本信息是可选项 template <class Archive> void save( Archive & ar, std::uint32_t const version ) const { ar( a, b ); } template <class Archive> void load( Archive & ar, std::uint32_t const version ) { ar( a, b ); }};CEREAL_CLASS_VERSION(SomeData, 1);struct MyType{ int x; double y; SomeData s; template <class Archive> void serialize( Archive & ar, std::uint32_t const version ) { ar( x, y ); ar( s ); }};int main(){ std::ofstream os("out.bin", std::ios::binary); { cereal::BinaryOutputArchive ar(os); MyType m; ar( m ); } return 0;}
- Cereal library--从Boost到Cereal的过渡
- Cereal library--快速入门
- Cereal library--Serialization函数
- Cereal library--序列化类型
- Cereal library--一个C++11的序列化库
- cereal:C++实现的开源序列化库
- c++序列化库cereal使用介绍
- 从c++到java的简单过渡
- 从Flex3过渡到Flex4
- 从svn过渡到git
- 从Win32过渡到MFC
- 从Win32过渡到MFC
- 【从C++过渡到Lua】
- 从Ibatis过渡到Mybatis
- 【从C++过渡到Lua】
- 从C过渡到C++
- 从C过渡到C++
- 从ASP过渡到ASP.net遗留的二十大积习
- 各排序算法对比
- [读书笔记] 怎样读论文
- Pointers on C——10 Structures and Unions.6
- Git学习
- NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证
- Cereal library--从Boost到Cereal的过渡
- Pointers on C——10 Structures and Unions.7
- Java--集合
- UVALive4794[Sharing Chocolate] 状态压缩动态规划
- 机器学习&深度学习
- Pointers on C——10 Structures and Unions.8
- synchronized同步方法
- 搜索实现迷宫(队列)
- 集体智慧编程(5)——优化