Bug 17734 – __traits(isRef) cannot currently be used to distinguish l-value from r-value passing of `this`
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-08-08T18:33:00Z
Last change time
2017-08-08T20:42:30Z
Assigned to
nobody
Creator
per.nordlow
Comments
Comment #0 by per.nordlow — 2017-08-08T18:33:25Z
__traits(isRef) cannot currently be used to distinguish l-value from r-value passing of `this`:
# l-value passing:
S s = 42;
s.f();
# r-value passing:
S(42).f();
given that
struct SS
{
int x;
void f(int x);
}
This severly limits the possibilities of implenting C++-style expression templates to realize lazy evaluation in operator overloading in arithmetic types.
If this limitation were to be fixed, libraries such as gmp-d (which wrap the C-implementation GNU MP) could implement lowering of expressions such as (in the gmp case):
Z result = base^^exp % modulo
to the builtin
__gmpz_powm(result._ptr, base._ptr, expr._ptr, modulo._ptr)
See also: https://github.com/nordlow/gmp-d/#limitations
Comment #1 by schveiguy — 2017-08-08T18:52:21Z
This is because `this` is always accepted by reference, even for rvalues. This is, in fact, the only place an rvalue will bind to a reference.
So this is as designed, at least for __traits(isRef). I don't think there's any way to fix this, unless you templated each function and accepted `this` by value when called from rvalues.
I recommend closing, this enhancement isn't going to happen.
Comment #2 by andrei — 2017-08-08T19:09:53Z
Yeah likely won't happen. Also, it's a modularity issue - a function can't know inside how it was called. At best we could do that via overloading, but overall I don't see this being a good start. I recommend a closer look/discussion before opening an enhancement.
Comment #3 by per.nordlow — 2017-08-08T20:17:13Z
(In reply to Steven Schveighoffer from comment #1)
> I recommend closing, this enhancement isn't going to happen.
Can anyone think of an alternative way of finding out whether or not `this` is an r-value?
Comment #4 by andrei — 2017-08-08T20:24:41Z
Don't use methods. Instead, use regular functions with UFCS and overload on ref and non-ref to distinguish rvalues from rvalues.
Comment #5 by per.nordlow — 2017-08-08T20:33:31Z
(In reply to Andrei Alexandrescu from comment #4)
> Don't use methods. Instead, use regular functions with UFCS and overload on
> ref and non-ref to distinguish rvalues from rvalues.
But the whole issue is about operator overloading, and those (sadly) must be members (currently). Are there any plans of changing this?
Comment #6 by andrei — 2017-08-08T20:42:30Z
(In reply to Per Nordlöw from comment #5)
> (In reply to Andrei Alexandrescu from comment #4)
> > Don't use methods. Instead, use regular functions with UFCS and overload on
> > ref and non-ref to distinguish rvalues from rvalues.
>
> But the whole issue is about operator overloading, and those (sadly) must be
> members (currently). Are there any plans of changing this?
That would be a better angle for an enhancement request.