Boost logo

Boost Users :

From: Ronald Garcia (garcia_at_[hidden])
Date: 2004-12-20 17:37:09


Sorry that it has taken me another week to reply to this one. I've
been up to other things and not had time to think about it.

On Dec 14, 2004, at 7:40 AM, David Abrahams wrote:

> Ronald Garcia wrote:
>> Howdy again,
>>
>>
>> On Dec 13, 2004, at 10:49 PM, David Abrahams wrote:
>>
>>> Ronald Garcia wrote:
>>>>
>>>> ...
>>>> Around here (the Open Systems Lab at Indiana University), I've been
>>>> arguing against this property of C++ for a long time, specifically
>>>> that
>>>> the language does not allow you to bind temporary to a non-const
>>>> reference. I am under the impression that this behavior is meant to
>>>> "protect" the programmer from making certain mistakes, but the
>>>> grave
>>>> downside to this is that it also prevents a library writer from
>>>> using
>>>> proxy objects to mimic reference semantics.
>>>
>>> The only case I can think of where that's true is when the reference
>>> type is the same as the value type. If we allowed operator->
>>>
>> Is this a complete thought, or am I missing something?
>>
I'm still wondering where the above comment was going. What is the
rest of the sentence that starts "If we allowed operator->..."?

...

>>> Why can't you just return a const proxy?
>>>
>>
>> Here's the catch: A multi_array has const and nonconst versions of
>> the
>> various operations and I implemented my proxy objects to mimic that
>> behavior. For example, operator[] returns a subarray if the original
>> array is non-const, but a const_subarray if the original array is
>> const. Since I sometimes want the array to allow mutating operations
>> and sometimes not, I cannot merge the const and nonconst versions of
>> these operations in the proxies. I need both const and non-const
>> versions.
>> Thus:
>> subarray const&
>> and
>> const_subarray&
>>
>> behave alike.
>
> But do they need to? Why not have
>
> subarray const&
>
> behave like
>
> subarray&
>
> and
>
> const_subarray const&
>
> behave like
>
> const_subarray&
>

I had thought about this at the time and came to the following
conclusion (modulo the fog of time since I made the decision):

 From my perspective, it seems that if a template function has a
signature such as:
template <Container>
void my_function(Container& A);

Then that function expects to receive a mutable container type. In the
case that a function expects to receive an immutable container, the
signature is likely to be:

template <Container>
void my_function(Container const& A);

IIRC some templated functions are overloaded as above specifically to
handle these two cases.

I concluded that if I chose the design you describe above, namely that
"subarray const&" behave like "subarray&" and "const_subarray const&"
behave like "const_subarray&", then I would likely violate the
expectations of a template function. Objects of type subarray , the
mutable reference proxy, would be passed to the second function above.

Suppose for a moment that a one-dimensional subarray is passed to the
above function. Using the above design, A::operator[] would return a
mutable reference to an underlying data element, though a const
reference to the underlying data might have been expected. That
mutable reference could be accidentally mutated (for example, by a
similarly overloaded function that mutates in one case and does not in
the other).

In summary, I chose to have subarrays respect the constness built into
the language as well as the constness imposed by the choice of proxy
object (const_subarray or subarray).

To the best of my memory, this was my thinking at the time.

Cheers,
ron


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net