Boost logo

Boost :

From: Gennadiy Rozental (gennadiy.rozental_at_[hidden])
Date: 2004-05-23 18:36:52


> >> 1) I would rather see a single templated type, call it property<T>
> >> which took other template policy parameters denoting "readonly" etc.
> >
> > What is an advantage? Do you envision other types of properties?
>
> Property is a single concept with different variations. It is clearer to
me
> to make those different variations template parameters rather than
introduce
> them as different class templates.

Clarity is the matter of taste. And IMO could not be driving force in
selecting property<T,readonly> over readonly_property<T>.
IMO first version present more complex design (and less convenient, for
example in actual code it may look like
boost::property<T,boost::readonly> ). For such simple facility primary
driving force is usability. And you need more strong points to prefer more
complex design.

> >> 2) Why "obj.member.value = t" rather than "obj.member = t" ? Surely
> >> operator == can be overloaded for a write property.
> >
> > That's very important part of design to make sure that all write
> > access to the property value goes through .value. This way I could
> > textually see where my property get changed. In most cases I just
> > search for property.value in sources.
>
> It is extra code to remember for your users. The expression x.y =
somevalue
> is much easier to use/remember than x.y.value = somevalue. Why make your
> users pay for something which for you makes it only easier to find
something
> in your code ?

One of the primary reasons I use property instead of public member is an
ability to see exactly where property value is get modified (Would I want
x.y = ... syntax, I would just use public member). In multimillion code base
(not necessarily written by you) an ability to find all places where
property is modified is important. Also in my experience read access always
prevail write access. So I don't believe it's such a burden.

> >> 3) Why "n.p_name -> size()" rather than n.p_name.size()" ? The
> >> variable p_name is not a property of type pointer to std::string but
> >> rather a property of type std::string.
> >
> > Because you couldn't override operator. ;-)
>
> The expression "n.p_name" should create a copy of the property, and
applying
> the size() member function gives one the size of the copy. So
> n,p_name.size() is the correct syntax and not n.p_name -> size(). In my
> vision of properties, properties are not variables, but values ( ala
Borland
> or MS ). If one wanted to change the size of the property n.p_name, one
must
> write:
>
> std::string x(n.p_name);
> x.size(10);
> n.p_name = x;
>
> and not
>
> n.p_name.size(10); // This merely changes the size of a copy

No. here I completely disagree. property layer should be thin and completely
negligible at runtime. I would never agree to property design that require
for me to create a string copy to be able to modify the property. Also you
would never be able to make an expression n.p_name to create a copy of the
property. p_name has type property<...>. You may have implicit cast to proxy
that hold copy of the property. But whatever you do you will never be able
to make m.p_name.size( 10 ) valid.
   If I have a permission to modify the property I should be able to call
non-const property methods. If not I should be able to call const property
methods. I do not know other way (other then operator->) to achieve this.

> > Unfortunately it's quite frequent to have a need for write access.
> > First example is operator= for the owner class. To be able to
> > implement it you
> > need owner class to have write access to the property. And it does
> > not make property "less readonly". That's why I frequently use
> > BOOST_READONLY_PROPERTY( int, (foo) ) p_value;
> > Another idiom that frequently require exclusive write access for
> > some classes is Builder/Factory patterns. Let's say you read class
> > MyClassBuilder that responsible for constructing objects of that
> > class. In most cases you will be forces to make MyClassBuilder a
> > friend for all properties to allow
> > it to set the value. And again in most cases property is still
> > readonly in it's nature.
> > I am open for alternative design proposition, but usability is
> > major player here. After all it simple facility for simple needs.
>
> I understand the need, but I was really arguing semantics. I think
> "readonly" properties are truly readonly by everyone once they are
created.
> Another name for properties which can be changed only by certain select
> objects/functions, rather than "readonly", should be used.

Why? p_name is in it's nature readonly property of class node, but
deserializer should be able set a value to it when you read stored structure
from file. It does not change readonly-ness of the property IMO.

> > It's actually is more complex idiom than one I am trying to model.
> > But If you have a concrete proposition we may consider it.
>
> Essentially the idea is that getters and setters could be passed as
template
> parameters in the form of boost::function<etc.> type by the property
> creator. This would allow any function type of object to server as the
> property getter or setter by the class property creator. Boost::function
is
> an overall solution to function callback. Why not use it with properties
if
> it can be done ?

Because it clearly overkill for all my needs. And in my practice I almost
never had a need for something like that. But it shouldn't stop you from
working on policy based smart_property framework that would support
validation, custom setter/getter, e.t.c. Be aware though that solution
complexity should be justified by advantages over other conventional means.
For example, why not just have property with custom type MyCustomType.
MyCustomType definition may include all the features you mentioned. And I do
not see right away how it may be worse than what you propose. Definitely
simpler.

> If a property were a single type, it would be easier for a pure C++
> reflection method to simply find out all public properties of a class and
> present them as values which could be set by the end-user programmer at
> design time. Then when a certain object, represented by the design-time
RAD
> creator, is actually created at run-time, all of the properties are
> automatically set to the values which had been specified by the
> end-user-programmer at design time. This is the way C++ Builder's Object
> Inspector and Microsoft's .NET equivalent, called the Component Designer,
> actually work. Of course both those implementations are using their own
C++
> extensions to "property" and "reflection", whereas if a property<T>
template
> mechansim were created and reflection became part of the language in 2008,
> it could be done purely in C++ with no language extensions.
>
> Of course it is just as viable to look for a family of "property" types in
a
> reflection mechanism as a single type, but I prefer the latter as a
> simplification mechanism.

I wouldn't say it's simplification. And I do not see that much difference
between one class or two.

> I think the most important thing regarding my concept of a "property" is
> that it is a value, not a member variable. As such the value can be read
> and/or written but attempting to take the address of a property, or access
> its theoretically underlying member variable, would be forbidden.

I do not see anything wrong to allow get property address if you have a
permission to do so. This is C++ not Java.
And I remember I had a need to do so once somewhere.

Gennadiy.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk