Does D really need something like const&?

Era Scarecrow rtcvb32 at yahoo.com
Fri Mar 1 17:37:26 PST 2013


On Saturday, 2 March 2013 at 01:15:20 UTC, Steven Schveighoffer 
wrote:
> The point is simple:
>
> foo(ref M m)
> foo(M m)
>
> An lvalue, yes, we want that to bind to ref.
>
> But an rvalue?  I want that to bind to foo(M m), otherwise I 
> would not have added that method.  The by-value version is 
> *more efficient* than the by-ref version with rvalues, even for 
> large structs.
>
> But what if I ALSO want to say that foo doesn't change m?  
> Well, that's easy!  I just do:
>
> foo(const ref M m)
>
> But this makes rvalues bind to that version too!  This is the 
> problem.  I want it to be ref, to avoid copies of a large 
> struct, and I want it to be const, for contract purposes, I 
> DIDN'T want it to accept rvalues.

  I know, that's what 'auto ref' would be for.

> The point is, there is a legitimate reason to Mark a parameter 
> const ref BESIDES wanting to have it bind to rvalues.

  I'm aware of that, sorry if I gave the wrong impression, but 
what I see in most of my cases is what I was referring to. We 
just got a similar problem where you have mutable data and 
immutable date, where there we have const as a middle ground that 
accepts both. We don't currently have the same thing for 
referencing.

  There are important reasons for having something referenced and 
having them as Rvalues, but when you don't care or need the 
middle ground is missing here.

> In my code base, I have actual comments that explain why I have 
> ordered certain operations the way I did!
>
> But we have more problems than just rvalue references.  The 
> compiler doesn't "see through" structs to know whether 
> something is an lvalue or an rvalue.
>
> Consider writing your own pointer type:
>
> struct T
> {
>     int *x;
>     void opUnary(string op)() if (op == "++") {++(*x);}
> }
>
> int x;
>
> T foo()
> {
>     return T(&x);
> }
>
> void main()
> {
>     auto t = foo;
>     t++; // ok
>     foo++; // Error: foo() is not an lvalue
> }
>
> That should not be an error, or I should at least be able to 
> tell the compiler "this is NOT an rvalue, even if it seems like 
> one".

  No, foo returns an lValue, however the ++ is likely wrong. The 
compiler could have an ingrained belief that ++ is an assignment 
operator meaning it requires an Lvalue, at which point the code 
is wrong. But ++ is just an operator for the struct, so I don't 
know.


More information about the Digitalmars-d mailing list