Tuesday, December 25, 2012
Compile time reflection in C++
*This is an example of why C++ needs compile time reflection(and modules)*
Unfortunately C++ does not have reflection--compile time or otherwise. It might be added in C++17, but here is one way of doing it now.
It uses the Boost Preprocessor library to generate compile time reflection data within a class.
A Reflected object looks like this:
After macro evaluation this generates an embedded type called "Reflection".
The Reflection structure contains N sub types labled [Member1 - MemberN], and an enum indicating how many members are present.
Each Member structure then contains the following data.
1. The type: (Member::type)
2. Access to member pointer (Member::GetMemberPtr())
3. Access to name of the reflected member (Member::GetName())
4. A type which indicates if the member is a function or variable, and if it is static or not(Member::member_class)
4. Optional meta data(basically user defined attributes). (Member::meta)
The meta tags can be optionally attached like so:
((_member)(Serialize)(Replicate)) //Serialize and Replicate being types you have declared
Some compile time functionality to walk this and generate something useful out of it is then needed.
Dealing with inherited base types is not difficult, add a type list which lists any base types, and then have your evaluation functions walk the full hierarchy.
Here is a link to the code if you are interested: reflection
Uses decltype and auto so some C++11 conformance is required.