How can I add reflection to a C++ application?

前端 未结 28 1652
感动是毒
感动是毒 2020-11-21 11:25

I\'d like to be able to introspect a C++ class for its name, contents (i.e. members and their types) etc. I\'m talking native C++ here, not managed C++, which has reflection

相关标签:
28条回答
  • 2020-11-21 11:43

    What are you trying to do with reflection?
    You can use the Boost type traits and typeof libraries as a limited form of compile-time reflection. That is, you can inspect and modify the basic properties of a type passed to a template.

    0 讨论(0)
  • 2020-11-21 11:45

    You can find another library here: http://www.garret.ru/cppreflection/docs/reflect.html It supports 2 ways: getting type information from debug information and let programmer to provide this information.

    I also interested in reflection for my project and found this library, i have not tried it yet, but tried other tools from this guy and i like how they work :-)

    0 讨论(0)
  • 2020-11-21 11:46

    It looks like C++ still does not have this feature. And C++11 postponed reflection too ((

    Search some macros or make own. Qt also can help with reflection (if it can be used).

    0 讨论(0)
  • 2020-11-21 11:47

    Reflection is not supported by C++ out of the box. This is sad because it makes defensive testing a pain.

    There are several approaches to doing reflection:

    1. use the debug information (non portable).
    2. Sprinkle your code with macro's/templates or some other source approach (looks ugly)
    3. Modify a compiler such as clang/gcc to produce a database.
    4. Use Qt moc approach
    5. Boost Reflect
    6. Precise and Flat Reflection

    The first link looks the most promising (uses mod's to clang), the second discusses a number of techniques, the third is a different approach using gcc:

    1. http://www.donw.org/rfl/

    2. https://bitbucket.org/dwilliamson/clreflect

    3. https://root.cern.ch/how/how-use-reflex

    There is now a working group for C++ reflection. See the news for C++14 @ CERN:

    • https://root.cern.ch/blog/status-reflection-c

    Edit 13/08/17:

    Since the original post there have been a number of potential advancements on the reflection. The following provides more detail and a discussion on the various techniques and status:

    1. Static Reflection in a Nutshell
    2. Static Reflection
    3. A design for static reflection

    However it does not look promising on a standardised reflections approach in C++ in the near future unless there is a lot more interest from the community in support for reflection in C++.

    The following details the current status based on feedback from the last C++ standards meeting:

    • Reflections on the reflection proposals

    Edit 13/12/2017

    Reflection looks to be moving towards C++ 20 or more probably a TSR. Movement is however slow.

    • Mirror
    • Mirror standard proposal
    • Mirror paper
    • Herb Sutter - meta programming including reflection

    Edit 15/09/2018

    A draft TS has been sent out to the national bodies for ballot.

    The text can be found here: https://github.com/cplusplus/reflection-ts

    Edit 11/07/2019

    The reflection TS is feature complete and is out for comment and vote over the summer (2019).

    The meta-template programing approach is to be replaced with a simplier compile time code approach (not reflected in the TS).

    • Draft TS as of 2019-06-17

    Edit 10/02/2020

    There is a request to support the reflection TS in Visual Studio here:

    • https://developercommunity.visualstudio.com/idea/826632/implement-the-c-reflection-ts.html

    Talk on the TS by the author David Sankel:

    • http://cppnow.org/history/2019/talks/

    • https://www.youtube.com/watch?v=VMuML6vLSus&feature=youtu.be

    Edit 17 March 2020

    Progress on reflection is being made. A report from '2020-02 Prague ISO C++ Committee Trip Report' can be found here:

    • https://www.reddit.com/r/cpp/comments/f47x4o/202002_prague_iso_c_committee_trip_report_c20_is/

    Details on what is being considered for C++23 can be found here (includes short section on Reflection):

    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0592r4.html

    Edit 4th June 2020

    A new framework has been released by Jeff Preshing called 'Plywood' that contains a mechanism for runtime reflection. More details can be found here:

    • https://preshing.com/20200526/a-new-cross-platform-open-source-cpp-framework/

    The tools and approach look to be the most polished and easiest to use so far.

    Edit July 12 2020

    Clang experiamental reflection fork : https://github.com/lock3/meta/wiki

    Interesting reflection library that uses clang tooling library to extract informtion for simple reflection with no need to add macro's: https://github.com/chakaz/reflang

    0 讨论(0)
  • 2020-11-21 11:47

    I did something like what you're after once, and while it's possible to get some level of reflection and access to higher-level features, the maintenance headache might not be worth it. My system was used to keep the UI classes completely separated from the business logic through delegation akin to Objective-C's concept of message passing and forwarding. The way to do it is to create some base class that is capable of mapping symbols (I used a string pool but you could do it with enums if you prefer speed and compile-time error handling over total flexibility) to function pointers (actually not pure function pointers, but something similar to what Boost has with Boost.Function--which I didn't have access to at the time). You can do the same thing for your member variables as long as you have some common base class capable of representing any value. The entire system was an unabashed ripoff of Key-Value Coding and Delegation, with a few side effects that were perhaps worth the sheer amount of time necessary to get every class that used the system to match all of its methods and members up with legal calls: 1) Any class could call any method on any other class without having to include headers or write fake base classes so the interface could be predefined for the compiler; and 2) The getters and setters of the member variables were easy to make thread-safe because changing or accessing their values was always done through 2 methods in the base class of all objects.

    It also led to the possibility of doing some really weird things that otherwise aren't easy in C++. For example I could create an Array object that contained arbitrary items of any type, including itself, and create new arrays dynamically by passing a message to all array items and collecting the return values (similar to map in Lisp). Another was the implementation of key-value observing, whereby I was able to set up the UI to respond immediately to changes in the members of backend classes instead of constantly polling the data or unnecessarily redrawing the display.

    Maybe more interesting to you is the fact that you can also dump all methods and members defined for a class, and in string form no less.

    Downsides to the system that might discourage you from bothering: adding all of the messages and key-values is extremely tedious; it's slower than without any reflection; you'll grow to hate seeing boost::static_pointer_cast and boost::dynamic_pointer_cast all over your codebase with a violent passion; the limitations of the strongly-typed system are still there, you're really just hiding them a bit so it isn't as obvious. Typos in your strings are also not a fun or easy to discover surprise.

    As to how to implement something like this: just use shared and weak pointers to some common base (mine was very imaginatively called "Object") and derive for all the types you want to use. I'd recommend installing Boost.Function instead of doing it the way I did, which was with some custom crap and a ton of ugly macros to wrap the function pointer calls. Since everything is mapped, inspecting objects is just a matter of iterating through all of the keys. Since my classes were essentially as close to a direct ripoff of Cocoa as possible using only C++, if you want something like that then I'd suggest using the Cocoa documentation as a blueprint.

    0 讨论(0)
  • 2020-11-21 11:47

    When I wanted reflection in C++ I read this article and improved upon what I saw there. Sorry, no can has. I don't own the result...but you can certainly get what I had and go from there.

    I am currently researching, when I feel like it, methods to use inherit_linearly to make the definition of reflectable types much easier. I've gotten fairly far in it actually but I still have a ways to go. The changes in C++0x are very likely to be a lot of help in this area.

    0 讨论(0)
提交回复
热议问题