$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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