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