ref?

Jason House jason.james.house at gmail.com
Sun Feb 15 11:28:22 PST 2009


Andrei Alexandrescu wrote:

> Walter and I have been discussing what the regime of statically-sized
> arrays should be. In short, the behavior that's most consistent with
> everything else is to treat them as values.

I'm curious, what use cases did you discuss?  I don't know of any functions where a statically sized array is passed in, so the whole ref vs. value has no meaning for the cases I'm aware of.



> This also brings the problems of e.g. containers - should they have
> consistent value semantics (like in STL) or consistent reference
> semantics (like in Java)? Or both, subject to a policy parameter?

I don't know about others, but I always pass around STL containers as either a reference or a const reference.  C++ is designed to allow everything be passed by value, but with little guarantee of what will happen.  It's up to the programmer to know what they're doing.  At least reference semantics are consistent...



> At any rate, it looks like the days of cheap by-value copying are over.
> Even today, large structs become onerous to pass by value. If copy
> constructors start being used, we can't simply assume that copying
> things around is not a problem.
> 
> Today we use:
> 
> void fun(T)(T value) { ... }
> 
> or
> 
> void fun(T)(ref T value) { ... }

Don't forget void fun(T)(in T value) { ... }


> to make a choice in parameter passing. But neither is perfect. The
> former copies too much, and the latter does not accept rvalues. C++ has
> found a solution to this problem in the guise of references to const
> objects. Those can accept lvalues and rvalues alike. It looked like a
> good solution at the time, but it's caused huge issues in other areas of
> the language, which ultimately led to a complicated feature called
> rvalue references. So I'd like to veer a different way.

I'd love to see some concrete examples of where that went wrong for C++.  If not, it's tough to judge what benefit alternatives provide.


> I was thinking of something like:
> 
> void fun(T)(ref? T value) { ... }
> 
> This really generates two overloads:
> 
> void fun(T)(ref T value) { ... }
> void fun(T)(T value) { return (cast(void (ref T)) fun)(value); }


Based on those two overloads, it appears the first can modify value, but the effect on the caller will still depend on if T is either a value or reference type.  This style of strange behavior seems really dangerous to me.



More information about the Digitalmars-d mailing list