Skip to content

Confusing operator overload semantics for serialization/deserialization #45

Description

@4x11

Description

In libraries like Boost.Serialization, serialization and deserialization are defined using free functions (non-member functions) with intuitive parameter order:

// deserialise – read data from stream into object
auto& operator>>(auto& stream, MyStruct& myData);

// serialise – write data from object into stream
auto& operator<<(auto& stream, const MyStruct& myData);

This follows the natural left-to-right data flow:

stream >> myData; // data moves from stream to myData (deserialization)

stream << myData; // data moves from myData to stream (serialization)

Hexi uses member operator overloads instead:

struct MyData
{
    // deserialise
    auto& operator>>(auto& stream);
    
    // serialise
    auto& operator<<(auto& stream) const;
};

This creates counter-intuitive semantics. Because the operators are defined as member functions, the logical reading becomes confusing:

auto& MyStruct::operator>>(auto& stream) { /*...*/ }

Its naturally reads as "take data from MyStruct and write it to stream". However, this method actually performs deserialization - reading from the stream into the struct.

Proposed solutions

  1. Use operator>> for serialization and operator<< for deserialization
  2. Change the API to use free function overloads instead of member functions::
// deserialise
friend auto& operator>>(auto& stream, MyStruct& myData);

// serialise  
friend auto& operator<<(auto& stream, const MyStruct& myData);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions