使用Boost对const成员进行类的序列化

use*_*155 3 c++ serialization constructor boost const

请考虑以下代码段

class tmp1
{
    const int a_;
    const double b_;   
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int ver)
    {
        ar & a_ & b_ ;
    }

public:
    tmp1(const itype a , const ftype b) : a_(a), b_(b)
    {}
};
Run Code Online (Sandbox Code Playgroud)

通过这样做,我可以将对象写入文件

tmp1 t1(2, 10.0);    
std::string filename ="D:/Temp/demofile.txt";
std::ofstream ofs(filename);    
boost::archive::text_oarchive oa(ofs);
oa<<t1;
Run Code Online (Sandbox Code Playgroud)

我想tmp1通过读取文件来构造另一个实例.理想情况下,我希望这发生在第二个构造函数中,它接受文件名并构造它.我该如何做到这一点?

我试过了

tmp1 t2(10, 100.0);
    std::ifstream ifs(filename);
boost::archive::text_iarchive ia(ifs);
ia>>t2;
Run Code Online (Sandbox Code Playgroud)

但VS2012编译失败,并显示以下消息

archive/detail/check.hpp(162): error C2338: typex::value
4>          \boost\boost_1_67_0\boost/archive/detail/iserializer.hpp(611) : see reference to function template instantiation 'void boost::archive::detail::check_const_loading<T>(void)' being compiled
4>          with
4>          [
4>              T=const itype
4>          ]
Run Code Online (Sandbox Code Playgroud)

我假设由于构件是const.我认为提升会抛弃const限定符,但似乎并非如此.

Ric*_*ges 8

你要找的是文档中的"非默认构造函数":

https://www.boost.org/doc/libs/1_67_0/libs/serialization/doc/index.html

你需要写一个重载

template<class Archive, class T>
void load_construct_data(
    Archive & ar, T * t, const unsigned int file_version
);
Run Code Online (Sandbox Code Playgroud)

所以对于类Foo,例如用一个整数和一个字符串构造,你会提供:

template<class Archive>
void load_construct_data(
    Archive & ar, Foo * t, const unsigned int file_version
)
{
    int a;
    std::string b;
    ar >> a >> b;
    new (t) Foo(a, std::move(b));
}
Run Code Online (Sandbox Code Playgroud)

  • @ user6386155通过const_cast访问对象仅在对象最初是可变的时才有效。在您的情况下不是,所以您提出的是不确定的行为。此外,强制转换方法要求Foo是默认可构造的。这对于具有const成员的对象是不合逻辑的。 (2认同)