Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2004-12-20 17:54:40


Ronald Garcia wrote:
> 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->..."?

I think I was going to say that if we allowed it to return a non-const
pointer when is_same<reference, value_type>::value == true, that would
handle the cases in question.

>> 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.

Yes. Those functions are, in my experience, always used to expose
references/pointers that have the right mutability. For example,

  template <Container>
  typename Container::value_type& operator[](Container&);

  template <Container>
  typename Container::value_type const& operator[](Container const&);

They _never_ have different operational semantics. There are several
ways to handle that with const proxies. For example,

  const_subarray<T>::value_type

could be the same as

   subarray<T>::value_type const

> 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.

I don't think that's a big deal.

> 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).

I don't think so; see above.

> 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.

Understandable, but perhaps this an example of the insufficient
imagination I was alluding to.

The way I see it, you're asking me to sacrifice the ability to provide
const-correctness for convenience, and I'm suggesting that no matter how
ugly it may be, there's a way to keep everything safe within the current
language.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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