? , .
, :
struct MyType
{
int fieldA;
int fieldB;
void setField(std::string const& field, std::string const& value);
};
setField , , . - ( ints, ... ), .
static std::map<std::string, Functor<MyType>*> M_Map;
template <class Type>
struct Functor
{
virtual void set(Type& t, std::string const& value) const = 0;
};
struct SetfieldA : public Functor<MyType>
{
virtual void set(MyType& t, std::string const& value) const
{
std::istringstream stream(value);
stream >> t.fieldA;
}
};
std::istringstream, , std::istream. , .
, , !
, .
#define INTROSPECTED(MyType_) \
private: \
typedef Functor<MyType_> intro_functor; \
typedef std::map<std::string, intro_functor const*> intro_map; \
static intro_map& IntroMap() { static intro_map M_; return M_; } \
public: \
static void IntroRegister(std::string const& field, intro_functor const* f){ \
IntroMap()[field] = f; } \
void setField(std::string const& field, std::string const& value) { \
intro_map::const_iterator it = IntroMap().find(field); \
if (it != IntroMap().end()) it->second->set(*this, value); }
#define INTROSPECT_FIELD(Class_, Name_) \
struct Set##Name_: public Functor<Class_> { \
virtual void set(Class_& t, std::string const& value) { \
std::istringstream stream(value); stream >> t.Name_; } } Setter##Name_; \
Class_::IntroRegister(#Name_, Setter##Name_)
:
struct MyType
{
INTROSPECTED(MyType);
int fieldA;
int fieldB;
};
INTROSPECT_FIELD(MyType, fieldA);
INTROSPECT_FIELD(MyType, fieldB);
MyType t;
t.set("fieldA", "3");
, : , , .