|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2003-05-10 22:36:24
"Lin Xu" <risingdragon3_at_[hidden]> writes:
>> template <class T, T v, char const*> struct member {};
>> template <class T> struct members;
>>
>> template <>
>> struct members<X>
>> : mpl::vector<
>> member<int(X::*)(double), &X::f, "f">
>> , member<char*(X::*), &X::x, "x">
>> , member<int&, X::y, "y">
>> >
>> {
>> };
> I realize that you were quickly drafting this code, but wouldn't you
> need to define the names as const char*,
No, but I would have to declare them as lvalues:
char eff[] = "f";
char ecks[] = "x";
char why[] = "y";
Well, a generator front-end can handle that behind the scenes.
> and that the member tempalte should take a member pointer?
The member template takes as its second argument whatever type you
specify as the first argument. You'll notice that they all take
member pointers except for the 3rd item, since it refers to a static
member.
> The problem is that string constants have to be defined *outside* the
> definition of the template, as I remember from discussion from a
> compile time string class. But you can't really do much compile time
> manipulation of strings, anyway.
I don't really need to do much, anyway ;-)
But you *can* do plenty, provided the representation is sufficiently hard
for humans to parse <wink>:
mpl::vector_c<char, 'f', 'o', 'o'>
> For starters, comparision (is_same) of template classes with string
> constants (predictably) fail when you define two different const
> char*'s that contain the same thing. I think that the string name
> should be relegated to the runtime aspect of reflection - unless,
> the only thing being supported is runtime reflection (perhaps in
> conjunction with dynamic_any).
I don't see much use for compile-time name reflection, but if we need
it we can always use the technique shown above. Binding the address
of the string as a template parameter just makes implementing the
reflection data much simpler, because there's no need for mixed
compile-/run- time structures.
> At compile time, the only way to give a member a unique identity is
> with some sort of tag class, which later on can be used to get the
> value:
>
> struct prop_x {};
> ...
> struct y { int x };
> //define the reflection
> y test;
> reflect<y>::get<prop_x>(test) = 10.4;
The *only* way? Come now! Anything that can be used as a template
parameter will do just as well, provided you can keep track of the
relationship between the different choices for this template
parameter and the member name.
> At runtime, of course, things are different. Something like this may
> be possible:
> template <> struct reflect<y> : public reflect_base<y> {
> MEMBER(x);
> };
>
> reflect<y>::bind_to(test)["x"] = 10;
>
> Comments?
I guess I'm not sure what the above is good for...
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk