Boost logo

Boost Users :

From: Joel de Guzman (joel_at_[hidden])
Date: 2007-03-09 20:10:41


David Abrahams wrote:
> on Thu Mar 08 2007, Christoph Duelli <duelli-AT-melosgmbh.de> wrote:
>> Given a struct like
>> struct X { int a; char b; float c; }
>> and some function-'template' f
>>
>> is it possible to 'generate' - preferably by means of templates, MPL or
>> something of the kind - variations of some function f for each of X's
>> fields?
>>
>> E.g. I'd like to have functions like
>> int getA() { return a; }
>> char getB() { return b; }
>> float getC() { return c; }
>> ...
>>
>> (The functions I have in mind are more complex, obviously, but the idea is
>> to generate one such function for all the fields of X.)
>> I would like to avoid writing a macro call or something per field, as I
>> would like the code to work (after recompiling it) even if the definition
>> of X is changed and some fields are added.
>> So, is there some generic 'iterator' over the fields of a struct?
>
> Nope.
>
> You might consider using Boost.Fusion and using a tuple instead of a
> struct. You won't be able to generate a family of overloaded
> functions at namespace scope, but you will be able to generate a
> family of overloaded (static) member functions.

You can also map your struct(s) to a fusion tuple. The mapping can be
a simple "tie". Example:

     fusion::vector<int&,char&,float&>
     map_struct(X& x)
     {
         return fusion::tie(x.a, x.b, x.c);
     }

Then you can refer to x.a through at_c<1>, x.b through at_c<2> and
x.c through at_c<3>.

If you want your fields to be non-positional (i.e. a field named "a"
can always be referred to somehow regardless of its position in
the struct), then you can use fusion::map and map various keyword
types to each of the fields. Example:

     struct a_;
     struct b_;
     struct c_;

     fusion::result_of::map_tie<
         a_, int&,
         b_, char&,
         c_, float&
>
     map_struct(X& x)
     {
         return fusion::map_tie<a_type, b_type, c_type>(x.a, x.b, x.c);
     }

Then you can refer to x.a through at_key<a_>, x.b through at_key<b_> and
x.c through at_key<c_>.

Regards,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

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