ref?
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sun Feb 15 07:50:13 PST 2009
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.
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?
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) { ... }
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 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); }
meaning that there are two fun instantiations, one actually doing the
work, and the other just forwarding rvalues to it.
There's one little extra thing that the feature does. A function may
want to return its incoming argument, in which case it might say:
ref? T fun(T)(ref? T value) { ... return value; }
in which case the generated code is:
ref T fun(T)(ref T value) { ... }
T fun(T)(T value) { return (cast(void (ref T)) fun)(value); }
I wanted to discuss this to gather more ideas and insights on the topic.
Andrei
More information about the Digitalmars-d
mailing list