Joseph Fradley wrote:
I have a problem that I would like to solve in the most generic non-intrusive way possible (such as boost serialization). What I want is to access class members both via it's initially designed accessors but also via a "const char *" key. In addition, I want to pass list of key's (via a vector of const char * or a single delimited multikey char *) to get nested member access.
For example: ... // these should be equivalent Point p; int val; val = p.x; val = p.getX(); p.getMemberValue("x", val);
// there also Rectangle r; int val; Point pVal; r.getMemberValue("corner:x", val); r.getMemberValue("corner", pVal);
Steven Watanabe wrote:
You could try something along these lines:
class indexable_base { public: virtual indexable_base* lookup(const char*) = 0; virtual const std::type_info& get_type() = 0; virtual void* get() = 0; };
Then you can put macros in the derived class like so:
class Rectangle : public indexable_base { DEFINE_LOOKUP() { DECLARE_VARIABLE(corner); } Point Corner; };
Which would expand to something like
class Rectangle : public indexable_base { template<class T> void getMemberValue(const char* key, T& out) { indexable_base result = lookup(key); if(typeid(T) == result->get_type()) { out = *(static_cast
(result->get())) } else { throw(std::bad_cast()); } } indexable_base* lookup(const char* key) { // split key at ":" and lookup call lookup_ recursively until all the keys are used up. } static void init() { map_.insert(std::make_pair("corner", &boost::bind(&Rectangle::corner, _1))); } Point corner; };
Steven, Thank you, I'm trying it now. But I'm a confused as to what type of map to create from your line : map_.insert(std::make_pair("corner", &boost::bind(&Rectangle::corner, _1))); I've just now read up on boost::bind and I can only see documentation of binding to member functions not member data. Could you elaborate? Joe