|
Boost Users : |
Subject: Re: [Boost-users] Get fields from struct
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2012-01-13 10:44:14
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_key<keys::name>(x) <<
> std::endl;
> std::cout << "Age: " << boost::fusion::at_key<keys::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 <typename OSTREAM, typename T>
OSTREAM& operator<<(OSTREAM& os, field_ref<T> const& p)
{
ostream_visitor v(std::cout);
apply(v,p);
return *this;
}
There are surely some boost related reflection libraries that I don't know
that it could be worth looking for as e.g. Boost.Mirror.
I don't know if you are looking for this behavior.
HTH,
Vicente
-- View this message in context: http://boost.2283326.n4.nabble.com/Get-fields-from-struct-tp4291964p4292528.html Sent from the Boost - Users mailing list archive at Nabble.com.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net