Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Шутки шутками, но чисто для уточнения: хотелось сделать сериализатор только на C++ и шаблонах (шаблоны — не C++ :-D) без использования внешних утилит (компилятора протобуфа)?
Потому как у протобуфа, как минимум, следующие профиты:
cout << something (или, в случае десериализатора, который я опустил, in >> something; if(in.rdstate()) return false;).stream << value << " ";, чтобы всё починить. На деле такой способ не очень хорош (зачем совать пробел в двоичный буфер?), поэтому я делаю так:// манипуляторы!11
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& delimiter( std::basic_ostream<CharT, Traits>& os ) {
return os << CharT(' ');
}
template< class CharT, class Traits >
std::basic_istream<CharT, Traits>& delimiter( std::basic_istream<CharT, Traits>& is ) {
return is; // при чтении париться о пробелах уже не надо
}
BitStream& delimiter(BitStream& bs) {
return bs; // ничего не надо делать -- ни при чтении, ни при записи
}
serialize(...) {
F::serialize(out, ...);
out << delimiter;
NextSerializer::serialize(out, ...);
}
deserialize(...) {
if(!F::deserialize(in, ...)) return false;
in >> delimiter; // вдруг будет вид потока, требующий считать разделитель?
return !in.rdstate() // ничего не сломалось при считывании разделителя
&& NextDeserializer::deserialize(in, ...); // ничего не сломалось в рекурсии
}
StringField, а не буду использовать подход в лоб. Буду в base64 их конвертить, например.успешно выводит
7776666a
Возможно, статья сможет освободиться от них и даже стать приличным учебным материалом!
struct PointField {
template<typename OS> serialize(OS& out, const Point& p) {
Schema<IntegerField, IntegerField>::serialize(out, p.x, p.y);
}
};
struct PlayerField {
template<typename OS> serialize(OS& out, const Player& pl) {
Schema<PointField, PointField, VectorField>::serialize(out, pl.a, pl.b, pl.c);
}
};
if(error) return false; в каждой строке, писать которую вручную нам было бы тошно.А есть тесты насколько именно ваш сериализатор круче того же json'a? =)
Автору респект! Получилось идеоматично и компактно. Надеюсь статья позволит плодить меньше костылей в C++ проектах (ведь почти все изобретают свой сериализатор).
P.S. Окромя flatbuffers можно обратить внимание на Cap'n'Proto и Microsoft Bond. Возможно они решают задачу лучше.
Пишем сериализатор для сетевой игры на C++11