Hello all, I'm currently busy to get things like this working: struct person { std::string name; int age; }; int main(int argc, char **argv) { person p; p.name = "Matthijs" p.age = 1234; std::string key = "name"; // Now try to fetch the value based on the key string. std::cout << p.{key} << std::endl; // does not compile return 0; } Of course above doesn't work for obvious reasons. The closest I get is: struct person { std::string name; int age; }; namespace keys { struct name; struct age; } BOOST_FUSION_ADAPT_ASSOC_STRUCT( person, (std::string, name, keys::name) (int, age, keys::age) ); int main(int argc, char **argv) { person x; x.name = "Matthijs"; x.age = 1234; std::cout << "Name: " << boost::fusion::at_keykeys::name(x) << std::endl; std::cout << "Age: " << boost::fusion::at_keykeys::age(x) << std::endl; return 0; } Now my question, is there maybe another way to achieve this? Regards, Matthijs Möhlmann Cacholong
Matthijs Möhlmann wrote
Hello all,
I'm currently busy to get things like this working:
struct person { std::string name; int age; };
int main(int argc, char **argv) {
person p; p.name = "Matthijs" p.age = 1234;
std::string key = "name";
// Now try to fetch the value based on the key string. std::cout << p.{key} << std::endl; // does not compile
return 0; }
Of course above doesn't work for obvious reasons.
std::cout << "Name: " << boost::fusion::at_keykeys::name(x) << std::endl; std::cout << "Age: " << boost::fusion::at_keykeys::age(x) << std::endl;
Now my question, is there maybe another way to achieve this?
I guess that what you want is a some kind of run-time reflection.
int main(int argc, char **argv) {
person p;
p.name = "Matthijs"
p.age = 1234;
std::string key = "name";
std::cout << field_at_key(p, key) << std::endl;
return 0;
}
The problem is that we don't know which type person_field_at_key should
return. We could type erase the result type and get it lazily when the value
is required.
The following maps to a field reference
template <typename T>
field_ref<T> field_at_key(T const& p, std::string const& key)
{
return field_ref<T>(p,key);
}
We could overload an apply function specific for field_ref<person>
template <typename Visitor>
void apply(Visitor& v, field_ref<person> const&p)
{
if (key=="name") v(p.get_person().name);
else if (key=="age") v(p.get_person().age);
}
The preceding code could be generated by a macro, as it is done STRUCT_ADAPT
We could the define a OSTREAM visitor as follows
template <typename OSTREAM>
struct ostream_visitor {
OSTREAM& os_;
otream_visitor(OSTREAM& os) : _os(os)
template <typename T>
operator(T const& v) { os_ << v; }
};
template
participants (2)
-
Matthijs Möhlmann
-
Vicente Botet