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.