Topic: for each member of a structure/class ?
Author: nagle@animats.com (John Nagle)
Date: Fri, 28 Dec 2007 21:46:27 GMT Raw View
Martijn Meijering wrote:
> Roman.Perepelitsa@gmail.com wrote:
> > What would be really useful is something
>> like restor suggested in this thread: ability to get tuple
>> of references to all members of a struct/class.
>
> Agreed.
>
>> But
>> I'm not aware of any proposals regarding this subject.
>
> Neither am I, but I think it would be quite an important addition. Not
> quite as important as modules, but still quite important.
I'd once given this some thought. But in a language that doesn't
have tuples, and barely has arrays with known length, it's difficult to
create an appropriate data structure.
I suppose something could be hacked up involving recursive template
instantiation. One could have a primitive like like "typeof_field(T,N)",
returning the type of field N of object T. Then, using recursive
templates, one could iterate through the fields. It might also be
useful to have "field_count(T)", for termination checking.
This would be useful for automatically generating marshalling code
at compile time. That can be a substantial win, because marshalling code
usually consists of trivial copies slowed down by the run time machinery
which invokes them.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Fri, 4 Jan 2008 11:33:37 CST Raw View
On 28 d c 2007, 22:46, na...@animats.com (John Nagle) wrote:
> I'd once given this some thought. But in a language that doesn't
> have tuples, and barely has arrays with known length, it's difficult to
> create an appropriate data structure.
There is no problem with C++ tuples. They're simply automatically-
generated structures with some reflection information (ability to know
the number of members, ability to retrieve the i-th member, ability to
retrieve the type of the i-th member).
But anyway why would you want to use tuples to expose full class
reflection? They're not enough to support all of the reflection needs
of C++ classes (member variables, overloaded member functions, static
member variables and functions, typedefs).
I believe this design is fairly good:
template<typename T>
struct reflection {};
template<> struct reflection<MyClass>
{
typedef mpl::map<
mpl::pair<
mpl::vector_c<char, 'm', 'e', 'm', 'b', 'e', 'r', '1'>,
a_function_object_type_which_allows_to_get_the_member_and_exposes_its_type
>,
....
> member_variables;
typedef .... member_functions; /* same as member_variables except
the function object must expose and allow to call multiple overloads
*/
typedef .... typedefs; /* nothing more than a type -> type map */
typedef .... static_member_functions; /* same as
member_functions, except we don't take an object in the functor
constructor */
typedef .... static_member_variables; /* same as
member_variables, except we don't take an object in the functor
constructor */
typedef .... constructors; /* a single function object */
typedef .... base_classes; /* a list of base types */
};
I'd say only public interface needs to be exposed, but protected and
private interfaces could also be exposed in a reflection_protected/
private for example.
The only problem is how to expose the type of template member
functions.
Doing so would be quite complicated.
For example, to encode
template<int A, typename B> typename B::type func(B&, void*),
we could expose the template parameters and then construct an
expression tree for each element of the signature.
typedef mpl::vector<
mpl::pair< mpl::vector_c<char, 'A'>, value_parameter<int> >,
mpl::pair< mpl::vector_c<char, 'B'>, type_parameter >
> parameters;
typedef mpl::vector<
static_var_bind< ref<1>, mpl::vector_c<char, 't', 'y', 'p', 'e'>
>, /* ref<1> stands for second template parameter */
add_ref< ref<1> >,
type<void*>
> signature;
with appropriate types providing reflection:
- value_parameter and type_parameter
- ref and type
- static_var_bind, static_func_bind, add_ref, add_const, add_volatile,
add_pointer, and probably others, such as passing the parameter as a
parameter to another template or building a function type which
contains a parameter type.
Another simpler but less powerful way would be to expose the template
parameters and then allow the signature to be extracted given the
parameters.
typedef mpl::vector<
mpl::pair< mpl::vector_c<char, 'A'>, value_parameter<int> >,
mpl::pair< mpl::vector_c<char, 'B'>, type_parameter >
> parameters;
template<int A, typename B>
struct signature
{
typedef typename B::type (B&, void*) type;
};
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]