Is it possible to serialize and deserialize a class in C++?

前端 未结 13 2680
我寻月下人不归
我寻月下人不归 2020-11-22 02:18

Is it possible to serialize and deserialize a class in C++?

I\'ve been using Java for 3 years now, and serialization / deserialization is fairly trivial in that lang

13条回答
  •  梦毁少年i
    2020-11-22 02:59

    I'm using the following template to implement serialization:

    template  struct Serializer
    {
        template 
        static void serializeImpl(const T &object, OutputCharIterator &&it)
        {
            object.template serializeThis(it);
        }
    
        template 
        static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
        {
            return T::template deserializeFrom(it, end);
        }
    };
    
    template 
    void serialize(const T &object, OutputCharIterator &&it)
    {
        Serializer::serializeImpl(object, it);
    }
    
    template 
    T deserialize(InputCharIterator &&it, InputCharIterator &&end)
    {
        return Serializer::deserializeImpl(it, end);
    }
    
    template 
    void deserialize(T &result, InputCharIterator &&it, InputCharIterator &&end)
    {
        result = Serializer::deserializeImpl(it, end);
    }
    

    Here T is the type you want to serialize Mode is a dummy type to differentiate between different kinds of serialization, eg. the same integer can be serialized as little endian, big endian, varint, etc.

    By default the Serializer delegates the task to the object being serialized. For built in types you should make a template specialization of the Serializer.

    Convenience function templates are also provided.

    For example little endian serialization of unsigned integers:

    struct LittleEndianMode
    {
    };
    
    template 
    struct Serializer<
        T, std::enable_if_t::value, LittleEndianMode>>
    {
        template 
        static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
        {
            T res = 0;
    
            for (size_t i = 0; i < sizeof(T); i++)
            {
                if (it == end) break;
                res |= static_cast(*it) << (CHAR_BIT * i);
                it++;
            }
    
            return res;
        }
    
        template 
        static void serializeImpl(T number, OutputCharIterator &&it)
        {
            for (size_t i = 0; i < sizeof(T); i++)
            {
                *it = (number >> (CHAR_BIT * i)) & 0xFF;
                it++;
            }
        }
    };
    

    Then to serialize:

    std::vector serialized;
    uint32_t val = 42;
    serialize(val, std::back_inserter(serialized));
    

    To deserialize:

    uint32_t val;
    deserialize(val, serialized.begin(), serialized.end());
    

    Due to the abstract iterator logic, it should work with any iterator (eg. stream iterators), pointer, etc.

提交回复
热议问题