temporary objects are not allowed to be pass by ref anymore
Denis Koroskin
2korden at gmail.com
Wed Apr 29 02:35:28 PDT 2009
On Sun, 19 Apr 2009 23:52:02 +0400, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> Now onto why ref was disallowed to bind to an rvalue. This is because
> some functions take things by ref intending to change them. Passing an
> rvalue is in such cases a bug.
>
> I agree there are functions that only want to use ref for speed
> purposes. I suggested Walter to use ref? for those. ref? means it could
> be an rvalue or an lvalue.
>
>
> Andrei
I don't understand why it is a bug, could you please elaborate on it?
But anyway, why disallow pass-by-const-ref? It won't be modified anyway!
struct Rect
{
int x, y, w, h;
}
Rect get()
{
Rect r;
return r;
}
void pass(ref const(Rect) rect)
{
}
void main()
{
pass(get());
}
Error: function test.pass (ref const(Rect) rect) does not match parameter types (Rect)
Error: get() is not an lvalue
Also note that if you are right, and modifying a temporary is a bug, then C++ is in a winning position here, because its const system is tail-const, and that's exactly what is required here - you can't modify a variable, but you can mofify whatever it points to.
We could have this behavior, too, by passing final-ref, not const-ref. Final qualifier means that an object it is applied to won't be modified, but it makes no statements about transitivity. Essentially, that's what C++ const does.
Here is an example:
struct RefCounted(T)
{
T* obj; // includes "int numReferences;" intrusively.
}
void passObject(ref final(RefCounted!(Foo)) foo)
{
auto copy = foo; // increments reference counter. Note that this don't modify the foo itself, only object which is available through it.
}
// passObject(new Foo()); // doesn't work, can we do anything with it? I'd like to hear your ideas.
passObject(RefCounted!(new Foo())); // allowed!
More information about the Digitalmars-d
mailing list