1. 4
  1.  

  2. 2

    If you only care about public fields, there’s another trick that you can use. C++17 structured binding means that you can extract fields individually or assign structures to tuples. With some templating, you can then generate functions that decompose arbitrary structures and operate individually on each of their fields.

    1. 2

      A bit confused by this post as it doesn’t explain how you go on to add any useful information to this reflection system.

      1. 1

        I did something similar, but at the same time something completely different to achieve reflection.

        I use empty structs as type hints and then realise them through specialised storage classes.

        namespace schema {
        struct Int32{};
        
        template<typename T>
        struct Array {};
        }
        namespace encoding {
        struct Native {};
        }
        template<typename Schema, typename Encoding>
        class data;
        
        template<typename T>
        class data<schema::Array<T>, encoding::Native> {
        private:
          std::vector<data<T, encoding::Native>> values_;
        public:
        .....
        };
        
        template<>
        class data<schema::Int32, encoding::Native> {
        private:
          typename native_data_type<schema::Int32>::type value_;
        };
        

        I simplified a lot though. This gives several advantages.

        • It allows you to implement multiple encoding backends which may be things like JSON or protobuf ( or a zero-encoding like format capnproto / flatbuffer ) which allows easy conversion since I can build templated transcoders.
        • The layout is known during compile time. Structs are possible with c++20 since you can use string_literals in template arguments there.
        • You can add arbitrary types in your type system. For Minecraft you can add a NBT struct and extend decoding/encoding + storage classes if you need them.
        • You have a bit more control over your types. Macro reflection allows for any random type to be added without control checks how feasible they are.
          Basically you are building your own type system.

        Edit: I mentioned minecraft since they use a lot of different behaviours during encoding. For example they have a type called NBT (N-something Binary Tag) which is basically BSON wrapped again in a binary encoding transport format ( A lot of funky encoding with multilayer diy-compression and so on. The protocol layer additionally uses deflate depending on the package size ).
        For these cases I still need to figure out how to express the encoding in a better way. Which would also be beneficial for any encoding which wraps other encodings like http or tls (I call it encoding here since from my implementation point of view they don’t differ too much).