Как повысить сериализацию на самом деле сохранить константный объект

Рассматривая следующий пример сериализации, как boost справляется с сохранением данных, когда эти данные являются константными, а функция сериализации не является константной функцией?

Есть ли где-нибудь конст-бросок?

  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);
}

2

Решение

Насколько я могу судить, константность действительно отбрасывается перед сохранением объекта. Я думаю, что соответствующий код находится в 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()
);
}

Перед вызовом этого метода ссылка на сериализованный объект превращается в const void *, соответствующий второму параметру здесь. Константность этого указателя отбрасывается, а результирующий указатель приводится к соответствующему типу указателя, который затем разыменовывается.

Это поднимает вопрос о возможности вызова неопределенного поведения при попытке сериализации const объект: если serialize Функция member / free каким-то образом изменяет объект, а затем создает const объект и сохранение его в архиве будет неопределенным поведением и останется незамеченным во время компиляции!

Если вы разделите функцию на save а также loadтогда вы должны отметить save как const, что предотвращает случайное изменение объекта.

2

Другие решения

Других решений пока нет …