Have you checked out the PFR library (perfect flat reflection)? I've coupled this with the magic-enum library to good effect.
PFR can be rewritten in very little code, assuming c++14(?); magic-enum is long enough to just use.
I generally have one TU for just serialization, and don't let PFR and magic-enum "pollute" the rest if my code. This keeps compile times reasonable. (The other is to uniquely name the per-type serializer: C++'s overload resolution is O(n^2)). I then write a single-definition forwarding wrapper (a template) that desugars down to the per-type-name serializers. It strikes a good balance between hand-maintenance, automatic serialization support, and compile-time cost.