On Thursday, 10 January 2013 at 16:42:09 UTC, Tommi wrote:
...which won't compile because T(4) is an rvalue, and according
to D, rvalues can't be passed as ref (nor const ref). I don't
know which one is flawed, my analogy, or the logic of how D is
designed.
My analogy is a bit broken in the sense that methods actually see
their designated object as a reference to lvalue even if it is an
rvalue. But I don't think that affects the logic of my main
argument about scope arguments.
A more strict language logic would be inconvenient.
But, this logic does introduce a discrepancy between non-member
operators and member operators in C++ (which D actually
side-steps by disallowing non-member operators... and then
re-introduces by providing UFCS):
// C++:
struct T
{
int val = 10;
T& operator--()
{
--val;
return *this;
}
};
T& operator++(T& t)
{
++t.val;
return t;
}
int main()
{
_cprintf("%d\n", (--T()).val); // Prints: 9
_cprintf("%d\n", (++T()).val); // Error: no known conversion
// from 'T' to 'T&'
return 0;
}
// D:
import std.stdio;
struct T
{
int val;
int get()
{
++val;
return val;
}
}
int het(ref T t)
{
++t.val;
return t.val;
}
void main()
{
writeln(T().get());
writeln(T().het()); // Error: T(0) is not an lvalue
}