This is KF5-compatible, but duplicates all the
ki18n methods. It's also still needing 2-5x more memory than the macro-based approach, but unlike that allows easy mixing of different variants in the same message table. It is significantly more efficient than build a message table holding
KLocalizedStrings at runtime though.
A more invasive approach (source-incompatible/KF6) could be to have the existing ki18n functions return a
KLazyLocalizedString, and replicate most of
KLocalizedString's API in there to auto-convert on demand. Not sure yet whether that's worth it though.
Similarly more compact types for each variants that auto-convert to
KLazyLocalizedString could be an option to explore to get to the same memory cost as the macro-approach, but that is probably not worth it.
This obviously still misses more docs and tests, for now this mainly about discussing the general idea.