Boost logo

Boost Users :

From: Ronald Garcia (garcia_at_[hidden])
Date: 2004-12-13 23:15:44


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?

>> Taking an example from MultiArray, if I have an 2x2 multidimensional
>> array:
>> boost::multi_array<int,2> A(extents[2][2]);
>>
>> and a template function that takes some Random Access Sequence:
>>
>> template <Sequence>
>> process_sequence(Sequence& Seq) { /* ... */ }
>>
>> then I cannot pass this function the second "row" of my array using
>> the
>> syntax:
>> process_sequence(A[1]);
>
> 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.

>
>
> class multi_array
> {
> const mutable_proxy operator[](int);
> const immutable_proxy operator[](int);
> ...
> };
>
> Now mutable_proxy only needs one version of the array operators.
> Couldn't that work?
>

See my comment above. Also, is one of these member function
declarations missing a const qualifier? If so, then this is already
what I'm doing and it's not sufficient.

>> The
>> subarray operators manipulate the data stored in the original
>> multi_array that created the original subarray.
>>
>> In fact, the Matrix Template Library (MTL) ran into the same problem.
>> The library often creates a "view" of a matrix as an argument to a
>> subsequent function. But again, if the subsequent function takes
>> its
>> argument by reference (which it should if the argument is used as an
>> "out parameter"), then the result is a compile-time error. What was
>> their solution? I hate to admit this: const_cast.
>
> Did someone think about returning const proxies?
>
I know that while working on multi_array, I had some discussions with
Jeremy about this and it didn't work for what I was trying to do. That
was sometime around 2001 though, so the details are hazy. I've
unfortunately had trouble communicating my position, if only because
the details quickly fade from my memory each time the issue comes up.

> I'm not sure; have they used enough imagination?
>

Good question. I've thought about this on and off for a while and I
have yet to come up with or hear of a solution. I'm neither a
language lawyer nor a metaprogramming guru, so it's quite possible that
I'm overlooking something. :)

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