On Friday, 3 January 2014 at 03:59:50 UTC, Jonathan M Davis wrote:
On Friday, January 03, 2014 03:13:12 alex burton wrote:
struct Foo
{
};
void bar(ref Foo f)
{
}
void main()
{
bar(Foo()); //Error: function test.bar (ref Foo f) is not
callable using argument types (Foo)
}
I get the above error with 2.064 not with 2.060.
Is it a bug ?
Is it a feature ?
If so :
Why can't I take a non const ref to a temp struct - It might
look
a bit silly but I might be doing it to avoid copying.
I could still do this :
void main()
{
Foo f = Foo();
bar(f);
}
Which is equivalent AFAIK
ref parameters only accept lvalues. Foo() creates a temporary
and is not an
lvalue. If you want a function to accept rvalues, it has to not
take its
argument by ref. If you want to avoid copying lvalues and still
accept
rvalues, then you need to overload the function (one which
takes ref and one
which doesn't). And unlike in C++, constness has no effect on
whether ref
accepts rvalues. ref only ever accepts lvalues.
However, in the case of rvalues, ref doesn't save you anything
performance-
wise. No copy will occur. Rather, because it's an rvalue, it
can just move it
into the function's parameter rather than copying it. ref only
saves you
copying with lvalues.
- Jonathan M Davis
Thanks for this, although I tested in 2.064 and the above code
works using void bar(in Foo f), which would seem to contracdict
"constness has no effect on whether ref accepts rvalues" if I
understand it correctly.
After looking at the asm, it appears that the compiler doesn't
copy the struct when using a void bar(Foo f), but also can avoid
copying if a second function like bar is called from bar.
It appears that passing by value is what I need, and I should
trust the compiler.