7

Is there a way to enumerate the members of a structure (struct | class) in C++ or C? I need to get the member name, type, and value. I've used the following sample code before on a small project where the variables were globally scoped. The problem I have now is that a set of values need to be copied from the GUI to an object, file, and VM environment. I could create another "poor man’s" reflection system or hopefully something better that I haven't thought of yet. Does anyone have any thoughts?

EDIT: I know C++ doesn't have reflection.

union variant_t {
   unsigned int  ui;
   int           i;
   double        d;
   char*         s;
};

struct pub_values_t {
   const char*      name;
   union variant_t* addr;
   char             type;  // 'I' is int; 'U' is unsigned int; 'D' is double; 'S' is string
};

#define pub_v(n,t) #n,(union variant_t*)&n,t
struct pub_values_t pub_values[] = {
   pub_v(somemember,  'D'),
   pub_v(somemember2, 'D'),
   pub_v(somemember3, 'U'),
   ...
};

const int no_of_pub_vs = sizeof(pub_values) / sizeof(struct pub_values_t);
Mike
  • 1,760
  • 2
  • 18
  • 33
  • C++ does not have reflection. See http://stackoverflow.com/questions/359237/why-does-c-not-have-reflection – lothar May 20 '09 at 15:25
  • Thank you for the feedback. I know C++ doesn't have reflection. – Mike May 20 '09 at 15:32
  • 4
    @Mike If you know that C++ doesn't have reflection, doesn't render the question useless immediately? How can you enumerate anything like you ask for without some kind of reflection (built into the language or roll your own)? – lothar May 20 '09 at 15:53
  • 1
    @lothar The C++ standard doesn't define all that can be done with C++. For example, before STL where was not standard string class. This didn't mean C++ programs couldn't make uses of strings. – Mike May 20 '09 at 16:09
  • 2
    @Mike: that is a terrible comparison. There is a huge difference between what's available in the standard library and what is possible in the language itself. (namely that the standard library is *implemented* in the language itself). std::string offers nothing you couldn't have implemented yourself. reflection is a whole different ball o' wax. – Evan Teran May 21 '09 at 20:05

6 Answers6

4

To state the obvious, there is no reflection in C or C++. Hence no reliable way of enumerating member variables (by default).

If you have control over your data structure, you could try a std::vector<boost::any> or a std::map<std::string, boost::any> then add all your member variables to the vector/map.

Of course, this means all your variables will likely be on the heap so there will be a performance hit with this approach. With the std::map approach, it means that you would have a kind of "poor man's" reflection.

oz10
  • 153,307
  • 27
  • 93
  • 128
3

You can specify your types in an intermediate file and generate C++ code from that, something like COM classes can be generated from idl files. The generated code provides reflection capabilities for those types.

I've done something similar two different ways for different projects:

  • a custom file parsed by a Ruby script to do the generation
  • define the types as C# types, use C#'s reflection to get all the information and generate C++ from this (sounds convoluted, but works surprisingly well, and writing the type definitions is quite similar to writing C++ definitions)
James Hopkin
  • 13,797
  • 1
  • 42
  • 71
2

Boost has a ready to use Variant library that may fit your needs.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
2

simplest way - switch to Objective-C OR Objective-C++. That languages have good introspection and are full-compatible with C/C++ sources.

also You can use m4/cog/... for simultaneous generation structure and his description from some meta-description.

vitaly.v.ch
  • 2,485
  • 4
  • 26
  • 36
0

It feels like you are constructing some sort of debugger. I think this should be doable if you make sure you generate pdb files while building your executable.

Not sure in what context you want to do this enumeration, but in your program you should be able to call functions from Microsofts dbghelp.dll to get type information from variables etc. (I'm assuming you are using windows, which might of course not be the case)

Hope this helps to get you a little bit further.

Cheers!

rtn
  • 127,556
  • 20
  • 111
  • 121
0

Since C++ does not have reflection builtin, you can only get the information be teaching separately your program about the struct content.

This can be either by generating your structure from a format that you can use after that to know the strcture information, or by parsing your .h file to extract the structure information.

Philippe F
  • 11,776
  • 5
  • 29
  • 30