fusion
est une approche, mais pourquoi ne pas stocker vos « champs » dans un std::map
calée par un std::string
, où la charge utile est le boost::variant
...
-à-dire
struct generic
{
std::map<std::string, boost::variant<foo, bar, bob, int, double> > _impl;
};
et vous pouvez il suffit de rechercher la clé dans votre getter/setter ...
heck, envelopper le variant
dans un optional
et vous pourriez avoir des champs optionnels!
un exemple plus complexe:
class foo
{
public:
typedef boost::variant<int, double, float, string> f_t;
typedef boost::optional<f_t&> return_value;
typedef map<string, return_value> ref_map_t;
foo() : f1(int()), f2(double()), f3(float()), f4(string()), f5(int())
{
// save the references..
_refs["f1"] = return_value(f1);
_refs["f2"] = return_value(f2);
_refs["f3"] = return_value(f3);
_refs["f4"] = return_value(f4);
_refs["f5"] = return_value(f5);
}
int getf1() const { return boost::get<int>(f1); }
double getf2() const { return boost::get<double>(f2); }
float getf3() const { return boost::get<float>(f3); }
string const& getf4() const { return boost::get<string>(f4); }
int getf5() const { return boost::get<int>(f5); }
// and setters..
void setf1(int v) { f1 = v; }
void setf2(double v) { f2 = v; }
void setf3(float v) { f3 = v; }
void setf4(std::string const& v) { f4 = v; }
void setf5(int v) { f5 = v; }
// key based
return_value get(string const& key)
{
ref_map_t::iterator it = _refs.find(key);
if (it != _refs.end())
return it->second;
return return_value();
}
template <typename VT>
void set(string const& key, VT const& v)
{
ref_map_t::iterator it = _refs.find(key);
if (it != _refs.end())
*(it->second) = v;
}
private:
f_t f1;
f_t f2;
f_t f3;
f_t f4;
f_t f5;
ref_map_t _refs;
};
int main(void)
{
foo fancy;
fancy.setf1(1);
cout << "f1: " << fancy.getf1() << endl;
fancy.set("f1", 10);
cout << "f1: " << fancy.getf1() << endl;
return 0;
}
Je me demande pourquoi vous voulez ça? Même dans les langages qui le supportent directement, la réflexion est un hack utilisé pour contourner le mauvais code, ou du code bon marché pour les programmeurs paresseux. –
Vous vaincre le type de sécurité que vous offre C++. Qu'est-ce qui peut justifier l'échange d'un outil si simple et si solide avec un hack désordonné pour atteindre l'incertitude? – wilhelmtell
@wilhelmtell: J'essaie de trouver le bon équilibre. Je lis des valeurs provenant d'une source très incertaine, et elles doivent être analysées et traitées de manière générique. Seulement pour une petite partie d'entre eux je sais (et je veux savoir) le bon type. –