veselink1 / refl-cpp

Static reflection for C++17 (compile-time enumeration, attributes, proxies, overloads, template functions, metaprogramming).
https://veselink1.github.io/refl-cpp/md__introduction.html
MIT License
1.05k stars 76 forks source link

Is there a possibility of adding features like Boost.PFR? #70

Closed NickStrupat closed 2 years ago

NickStrupat commented 2 years ago

Hi, thank you for providing this great library.

The API of this project is very good, but the requirement of using macros is not ideal. There are some abilities to do reflection without macros, and they are used by Boost.PFR and magic_enum.

Have you looked into using these approaches to remove the need for calling macros in your library?

Thanks!

veselink1 commented 2 years ago

Thanks. I have explored these options quite heavily. However, they are simply not powerful enough. Boost.PFR provides "very basic reflection" (from their website description) because that's the most that can be accomplished without macros IMO.

RalphSteinhagen commented 2 years ago

@NickStrupat just to chime in what @veselink1 already hinted at.

We also looked heavily into macro-free reflection but believe that these are necessary at least until the compile-time reflection proposal is merged with the C++ standard (present estimate/hope is C++26).

IMHO there are at least two reasons that justify the macros:

  1. while the type-name is already accessible during compile-time, the field and method names within the structs are not. Thus one would either need to
    • duplicate the string literal field/method name by hand (<-> error prone),
    • use the macro-helper that wraps and creates the string-literal as a pre-parser step (IMHO more robust and also IDE-refactorable), or
    • use, for example, the AST parser of Clang's llvm backend which would exclude the compatibility with GCC and MSVC.
      1. The macro allows to declare only a sub-set of fields to be reflected upon (<-> has an impact on the speed of the visitor pattern) and -- optionally -- in a different order than the fields are declared. This is particularly important w.r.t. type evolution and if there are different type declarations between server/client or different processes.

Other non-macro-based reflection engines implicitly require that all fields are deflectable and always in the same order as their definition. This can be an issue w.r.t. nested types and if there are types that need to be mandatorily skipped.

All in all, I like the present refl-cpp functionality as it's close to what is being proposed to become part of the C++ standard. There are some aspects regarding member-function parameter type deduction that @veselink1 commented that this can be easily also implemented in the user-code.

NickStrupat commented 2 years ago

Thanks folks for the informative replies :)