|
Boost : |
From: Luis Pedro Coelho (deepblack9_at_[hidden])
Date: 2002-02-13 17:12:50
Em Quarta, 13 de Fevereiro de 2002 16:01, escreveste:
> When you do
> A.value = 100 ;
> how does the property 'value' receives &A?
>
> My point is that there is NO WAY to store &A inside 'value' at compile
> time. You can store &A::foo, but without &A this still requires runtime
> support.
Off the top of my head:
value doesn't know where A is, but it knows where it is and it knows that it
lies inside A. In typical implementations (the begginning of) A will lie in a
fixed offset from where value is.
So
void value::operator = (const int x) {
A* a = reinterpret_cast<A*>(reinterpret_cast<unsigned char*>(this) - offset);
a->set_value(x);
}
All we got to do is find a way to calculate OFFSET at compile time. I think
that something like:
T A::*ptr = &A::value;
A* A = reinterpret_cast<A*>(&ptr);
// <- I just use ptr, could be anything!
T* t = A->*ptr;
long offset = reinterpret_cast<unsigned char*>(t) - reinterpret_cast<unsigned
char*>(A);
Of course, we can do this in one constant expression inside the template
class definition:
enum { offset = (reinterpret_cast<unsigned char*>
(reinterpret_cast<unsigned char*>(&whatever)->*Ptr_to_member)
-
reinterpret_cast<unsigned char*>(&whatever)));
}
Where Ptr_to_member is passed as a template parameter.
Note that we have to write:
boost::property<A, &A::value, read<&A::get_x>, write<&A::set_x> > value;
This approach has at least one advantage: No need to store an extra pointer
to the parent in every property object. Also there is now no need to pass to
this as a constructor argument.
HTH,
-- Luis Pedro Coelho. Check out my game of Hearts, a card game, for KDE at: http://hearts.sourceforge.net/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk