C++ boost序列化实际上是如何保存const对象的

C++ boost序列化实际上是如何保存const对象的,c++,serialization,boost,constants,boost-serialization,C++,Serialization,Boost,Constants,Boost Serialization,考虑下面的序列化示例,当数据为常量且序列化函数不是常量函数时,boost如何处理保存数据的问题 某处有一个const cast吗 struct Settings { Settings(); uint32_t buffers_size; uint32_t messages; }; template < class Archive > void serialize(Archive& ar, Settings& se

考虑下面的序列化示例,当数据为常量且序列化函数不是常量函数时,boost如何处理保存数据的问题

某处有一个const cast吗

  struct Settings
  {
    Settings();
    uint32_t    buffers_size;
    uint32_t    messages;
  };

  template < class Archive >
  void serialize(Archive& ar, Settings& settings, unsigned int /*version*/)
  {
    using boost::serialization::make_nvp;
    ar 
      & make_nvp< uint32_t >("buffers_size", settings.buffers_size )
      & make_nvp< uint32_t >("messages", settings.messages);
  }
struct设置
{
设置();
uint32缓冲区大小;
uint32_t消息;
};
模板<类存档>
无效序列化(存档和ar、设置和设置、未签名整数/*版本*/)
{
使用boost::serialization::make_nvp;
应收账
&制作nvp(“缓冲区大小”,settings.buffers\u大小)
&制作nvp(“消息”,设置.消息);
}

据我所知,在保存对象之前,constance确实被丢弃了。我认为相关代码位于
oserializer.hpp

template<class Archive, class T>
BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
    basic_oarchive & ar,    
    const void *x
) const {
    // make sure call is routed through the highest interface that might
    // be specialized by the user.
    BOOST_STATIC_ASSERT(boost::is_const< T >::value == false);
    boost::serialization::serialize_adl(
        boost::serialization::smart_cast_reference<Archive &>(ar),
        * static_cast<T *>(const_cast<void *>(x)),
        version()
    );
}
模板
BOOST\u DLLEXPORT void oserializer::保存对象数据(
基础油和天然气,
常数void*x
)常数{
//确保调用路由通过可能发生错误的最高接口
//由用户进行专门化。
BOOST_STATIC_ASSERT(BOOST::is_const::value==false);
boost::serialization::serialize_adl(
boost::serialization::智能转换引用(ar),
*静态施法(常数施法(x)),
版本(
);
}
在调用此方法之前,序列化对象引用将转换为一个
常量void*
,对应于此处的第二个参数。该指针的常量被强制转换,生成的指针被强制转换为适当的指针类型,然后被取消引用

这就提出了一个问题,即在尝试序列化
const
对象时调用未定义行为的可能性:如果
serialize
成员/自由函数以某种方式修改了对象,那么创建
const
对象并将其保存到存档将是未定义行为,并且在编译时不会被注意到


如果将函数拆分为
save
load
,则必须将
save
标记为
const
,以防止意外修改对象。

我猜它会忽略
const
volatile
限定符,因为它们与将内容写入文件没有多大关系,网络流等。如果您需要常量正确性,您可以。@LucTouraille:load/save的问题是,代码被一分为二,这在维护方面很困难。如果序列化/反序列化完全对称,则使用单个函数编写它们是有意义的。我只是花了一些时间浏览Boost代码,看看序列化库是如何处理constness的,但我还没有找到一个明确的答案。我猜
const\u cast
是合理的,但这意味着在
serialize
函数中不要修改序列化对象,因为它会在序列化const对象时打开未定义行为的大门。是的,另一种选择是复制数据,但我不确定它在性能/内存使用方面是否有意义。它还需要一个复制构造函数