← Back to context

Comment by Jyaif

13 days ago

Your lib requires manually creating both a serializing and deserializing function. If the functions are out of sync, bad things happen.

Consider copying Cereal, which solves this problem by requiring you to create a single templated function ( https://uscilab.github.io/cereal/ )

Thanks, that is definitely a downside to the shift operator overloading approach. I'll take that onboard and investigate whether a single operator to handle both would mesh with the current design.

  • You can just use the boost.pfr technique to iterate fields though. Or if you want, starting from C++26 and e.g. clang-21: https://gcc.godbolt.org/z/G1TqP3a8P

        #include <print>
        #include <type_traits>
        
        namespace hexi {
          struct streamer { };
        
          template<typename T>
          void operator<<(streamer& s, const T& e) {
            if constexpr(std::is_integral_v<T>) {
              std::println("number: {}", e);
            } else if constexpr(std::is_aggregate_v<T>) {
              auto& [...mems] = e;
              (std::println("member: {}", mems), ...);
            }
          }
        }
        
        struct user_type {
            int x;
            std::string y;
        };
        
        int main() {
            hexi::streamer s;
            s << 123;
            s << user_type{.x = 456, .y = "foo"};
        }
    

    or with boost.pfr as a polyfill until then, which allows to do this back to C++14

Thanks again for this comment. Consider Cereal copied, now only a single function is required.