Subject: Re: [boost] [property] interest in C# like properties for C++?
From: Edward Diener (eldiener_at_[hidden])
Date: 2009-10-23 15:59:09
Olaf van der Spek wrote:
> On Fri, Oct 23, 2009 at 5:33 PM, Edward Diener <eldiener_at_[hidden]> wrote:
>> You are not talking about the access syntax of properties, as I define it,
>> so your "Unacceptable"s mean little to me. Of course if the syntax
>> limitations of a property implementation vis-a-vis direct manipulation of a
>> data value is unacceptable to you, then you just wouldn't use it.
> Don't you agree that string& name = c.name; name.size() is kinda
> ugly/unusable compared to just c.name->size() (possible) or
> c.name.size() (not possible, but ideal)?
No I don't think it is unusable, and its ugliness is petty subjective.
The c.name.size() is terser, I grant you, but my alternative of
c.name.getReference().size(), with that extra "getReference()", does not
seem to me so terrible. If I accede to "get" rather than "getReference"
then it is even shorter as c.name.get().size() with that extra "get()".
Of course I can program in some operator symbol, such as ->, with very
little effort so it becomes c.name->size() but I am uncomfortable with
an operator in this case because there is little precedence what
operator would make easy mnemonic sense.
I would love to be able to say c.name.size() but it can't be done in C++
AFAICS. BTW I very much like user-defined operators and have been a
vociferous critic of Java's refusal to add them to that language, so I
could probably be convinced to add a user-defined operator to my
eventually published implemetation of property if I felt others would
find one understandable. But it appears to me that the -> user-defined
operator is too embedded with the notion of "pointer" to use in my case.
>> My main goals/reasons for properties are:
>> 1) Syntactically treat a property as close as one can as a data member while
>> providing the ability to control the accessing of the data and the setting
>> of the data through callables ( functions, member functions, functors,
>> boost::function ).
>> 2) Have properties be a type.
>> 3) Have all value properties of an underlying T type share an underlying
>> base class and have all reference properties of an underlying T type share
>> an underlying base class.
>> 4) Provide means beyond just member functions for getting and setting values
>> and getting references.
> The main goal I guess is 1, as the others can be achieved with
> traditional get/set functions, right?
Traditional get/set functions are not to my mind always the clearest way
of implementing properties, even if they are the most popular.
Furthermore 2) and 3) were also done because I envision properties being
types as important to future standard C++ RAD programming environments.
>> I have more than just these goals, but the above are the main ones.
>> Properties are in one way syntactic sugar for the plethora of
>> get/retrieve/etc. and set/put/etc. member functions. I also acknowledge that
>> it is syntactically impossible to manipulate properties as directly as one
>> can manipulate data members as far as I can see. But properties are really
>> not a substitute for data members but rather for get-like and set-like
>> functions whose purpose is to access and manipulate a data value. After all,
>> in my view of value properties, the data does not have to exist in memory at
>> all, and I believe this is consistent with the implementation of properties
>> in other languages.
> That's right. And actually why I wanted to use a class reference property.
If there is a better way to do it than what I have imagined and
implemented in my own version, I would consider it, but reference
properties AFAICS means that the underlying data is returned by
reference. I don't see any way to get around that.
In my original implementation I did not have reference properties at
all. The value properties I currently implement can be used with backing
data which is actually a reference. The T type of the reference just
needs to be copy constructible in that case, that's all. But then I
thought about it longer and realized that if one did have a T & ( or T
const & ) as backing data one should be able to implement a reference
property which simply returned that reference. I further realized that
if the reference property was returned as T & and T were not const, the
property is read/write, otherwise it is just readable, which fits in
well with he trsditional concept of properties in other languages being
readable, writable, or read/write. In the case of a reference property
as I have implemented it there is no such thing as just a writable
reference property, but in the case of a value property there is.
Finally I wanted reference properties because user-defined classes
themselves could easily have their own properties and the theoretically
best way of setting class objects is by setting the properties in the
class and not by trying to set an object of that class as a whole.
>> Of course you can use "string & name()" and "void set_name(const string &)"
>> if you like instead, or you can even just have a public variable of "string
>> name" you directly access and manipulate. I can offer my criticism of the
>> first choice or the second choice but I think it is already well known.
> I know, and I agree.
>>>> My member function is actually currently called "getValue" for my
>>>> property but I have decided that it is a confusing name since one is
>>>> getting a reference, and have changed it to "getReference".
>>> How about just get()?
>> I rejected this because of a feeling that some implementations of C++ may
>> macroize ( create a C++ preprocessor macro ) from such a common term as
>> "get". The same goes for "set". I am aware that ideally macros should be
>> all uppercase, but many implementations and header files which should know
> Hmm, I'd consider such C++ implementations broken by design.
I do too and perhaps my reticence to use "get" ( and "set" ) is
ill-founded. I would still defend it by saying that "getValue" and
"getReference" are clearer mnemonically than just "get" even if I am
forcing the end user to type some extra characters if they find it
necessary to call the underlying function rather than use the operator T