boost::serialization сериализация базовых типов
От: yatagarasu Беларусь  
Дата: 26.01.10 15:41
Оценка:
Кто копался в boost::serialization ?
Как переопределить механизм сериализации типов — векторов, мапов и т.д. для собственного архива.
Нужно переопределить формат хранения списков. Тот что там принципиально не устраивает. (
Re: boost::serialization сериализация базовых типов
От: zaufi Земля  
Дата: 27.01.10 02:52
Оценка:
Здравствуйте, yatagarasu, Вы писали:

Y>Кто копался в boost::serialization ?

Y>Как переопределить механизм сериализации типов — векторов, мапов и т.д. для собственного архива.
Y>Нужно переопределить формат хранения списков. Тот что там принципиально не устраивает. (

ну по тупому если... допустим у тебя есть класс мембером которого является вектор:

class my_data
{
    std::vector<some_type> m_vect;
    ...
};

доки говорят нам что при реализации метода serialize нужно просто этот датамембер сериалайзить... ну както так:

    ar && m_vect;


но это именно и не устраивает с твоих слов (чем же?)... ну раз не нравится бустерная реализация можно сделать свою...
пишем пару методов (my_collection_save/my_collection_load):
сохраняем в архив размер и далее for_each по всем элементам сохраняем их индивидуально... загрузка соответственно должна сначала прочитать количество элементов и далее цикл (от нуля до прочитанного значения) загружающий поэлементно из архива...
и дергаем соответствующий метод вместо ar && m_vect...

доки не читал и на вскидку не помню как штатно переопределить сериализацию стандартных контейнеров... поэтому сразу пошел посмотреть в сорцы.
ситуация вопщем такова: возмем например реализацию сериализации вектора... это шаблонная (раумеется) функция со следующей сигнатурой:

template<class Archive, class U, class Allocator>
inline void serialize(
    Archive & ar,
    std::vector<U, Allocator> & t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}


т.е. как видно отсюда чтобы "переопределить" ее не реально... все что мы можем сделать это предложить более подходящую перегрузку данной функции. что сделать также не просто -- она и так уже достаточно специализирована под вектора... все что мы можем предложить это сделать перегрузку с более подходяцим типом архива... ну там бинарный, текстовый, xmlный... не знаю каким ты там пользуешься... может своим какимто? -- если да то проблем вообще нет... рисуем перегрузку (можно, и нужно в том пространстве имен где у тебя определен твой архив)

template <class U, class Allocator>
inline void serialize(
    my_archive& ar,
    std::vector<U, Allocator>& t,
    const unsigned int file_version
){
    // TBD
}


второй way: если присмотреться на реализации других контейнеров, окажется что все они вызывают split_free, которая объявлена так:

template<class Archive, class T>
inline void split_free(
    Archive & ar,
    T & t,
    const unsigned int file_version
){
    ...
}


т.е. оа общая для всех контейнеров и всех архивов... опять таки можно сделать перегрузку с более подходящими типами параметров -- в данном случае либо уточнять тип архива, либо тип контейнера... (но рисовать ее придется в бустерном пространстве имен)

// например заточим ее под вектора...
template<class Archive, class U, class Allocator>
inline void split_free(
    Archive & ar,
    std::vector<U, Allocator>& t,
    const unsigned int file_version
){
    ...
}
// и так для всех контейнеров...


варнинг: вариант с перегрузками (особенно split_free) я считатю "грязным хаком" -- ибо закладываться на детали реализации не клёва... сеня они одни, завтра другие...

поэтому порекомендовал бы тебе путь №1 -- юзать свою сериализацию коллекций вместа шташной
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.