Search code examples
c++boostmacrosintrospection

Is there a good way of setting C/C++ member variables from string representations? (introspection-lite)


I've got a struct with some members that I want to be able to get and set from a string. Given that C++ doesn't have any introspection I figure I need some creative solution with macros, the stringize operator and maybe boost::bind. I don't need full serialization or introspection, more an 'introspection-lite'

I'd like to have something along the lines of this:

struct MyType {
  int  fieldA;
  int  fieldB;
};
DECLARE_STRING_MAP(MyType,fieldA);
DECLARE_STRING_MAP(MyType,fieldB);

MyType t;
SET_VALUE_FROM_STRING(MyType,t,"fieldA","3")    

Rather than have a huge if statement.

Any idea if there's a neat solution to this?

Related question: Object Reflection

EDIT: Thanks to maxim1000 for the 'map to int Type::*' trick -- this worked for me:

#define DEFINE_LOOKUP_MAP(Type) std::map<AnsiString,int Type::*> mapper 
#define ADD_FIELD_MAPPING(Type, Field) mapper[#Field]=&Type::Field 
#define SET_FIELD_FROM_MAP(Type, Field, var, value) var.*(mapper[#Field])=value    

DEFINE_LOOKUP_MAP(MyType); 
ADD_FIELD_MAPPING(MyType, fieldA); 
ADD_FIELD_MAPPING(MyType, fieldB); 

SET_FIELD_FROM_MAP(MyType, fieldA, obj, 3);

Solution

  • If all of them have the same type, you can use something like this:

    std::map<std::string,int MyType::*> mapper;
    mapper["fieldA"]=&MyType::fieldA;
    mapper["fieldB"]=&MyType::fieldB;
    ...
    MyType obj;
    obj.*(mapper["fieldA"])=3;