What you ask for is possible with a little bit of advance preparation. Your ultimate goal is to access a variable by a string entered at runtime.
Let's first look for any method at identifying a member selectively at runtime. That's what pointer-to-members are for. Quick example:
void set_member( numbers& target, double numbers::*which_member, double value )
{
target.*which_member = value;
}
set_member(Input, &numbers::x, 6.0);
set_member(Input, &numbers::y, -3.14);
In your example, all the member variables are the same type, so this gets us really close. All that we need in addition is a mapping from the name to the pointer-to-member.
std::map<std::string, double numbers::*> numbers_members =
{ { "x", &numbers::x },
{ "y", &numbers::y },
{ "z", &numbers::z } };
void set_named_member( numbers& target, set::string which_member, double value )
{
target.*(numbers_members[which_member]) = value;
}
set_member(Input, member_variable, variableValue);
Making the member map can be made a bit easier using a macro using the stringizing operator:
#define member(Type,MemName) { #MemName, &Type::MemName },
This can even be automated using some static analysis tool that produces a list of members by type (for example, the XML output format from the doxygen tool contains all the needed information; that plus a perl script launched by your makefile can give fairly effective reflection capability).
If you want to handle members of varying types, it gets a little more complicated. You will need to define an interface that works on all types, maybe it accepts the value as a string, and performs type-specific parsing (boost::lexical_cast
is a reasonable choice for that), before assigning the member. Such a member-of-arbitrary-type assigner could be implemented using templates.
Then you map object would go from the member name to this member-assigner functor. When calling the functor, you would pass in the object instance and the string representation of the value.