DIP 1016--ref T accepts r-values--Final Review
Steven Schveighoffer
schveiguy at gmail.com
Mon Nov 19 15:23:14 UTC 2018
On 11/18/18 10:55 AM, Rubn wrote:
> On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
>> On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
>>> For this what about if there are multiple parameters? How many
>>> overloads do you have to define to get this behavior?
>>
>> I'd assume a single one. It should be analogous to this:
>>
>> ```
>> void lval_only(uint x, short y) @disable;
>> void lval_only(int x, int y);
>>
>> void main()
>> {
>> byte y = 1;
>> lval_only(100_000, y);
>> }
>> ```
>>
>> The disabled function is preferred, so this doesn't compile. As
>> by-value params are to be preferred for rvalue args in overload
>> resolution, the single overload should do in your example.
>>
>> ---
>>
>> I'm a huge fan of this DIP and have been wanting this in the language
>> literally since the day I wrote my first D code, immediately stumbling
>> into this limitation (but fortunately not losing much interest due to
>> numerous advantages and syntax loveliness).
>
> If that's the case then it'll look something like this, for just 3
> parameters if you want the old behavior:
>
> void lval_only(int x, int y, int z) @disable;
> void lval_only(int x, int y, ref int z) @disable;
> void lval_only(int x, ref int y, ref int z) @disable;
> void lval_only(ref int x, int y, ref int z) @disable;
> void lval_only(ref int x, ref int y, int z) @disable;
> void lval_only(int x, ref int y, int z) @disable;
> void lval_only(ref int x, int y, ref int z) @disable;
>
> void lval_only(ref int x, ref int y, ref int z);
>
> Not really ideal, I might be missing one, hard to tell.
>
We can reduce to linear growth using auto ref:
void lval_only()(int x, auto ref int y, auto ref int z) @disable
void lval_only()(ref int, int, auto ref int) @disable
void lval_only(ref int, ref int, int) @disable
Still not ideal though. I tried auto ref for all 3, but that means it
will match both the template and the real function.
I tried using a constraint, but not sure how to get the parameter
ref-ness in a neat way inside the constraint. This does work:
void lval_only()(auto ref int x, auto ref int y, auto ref int z)
@disable if (!__traits(isRef, x) || !__traits(isRef, y) ||
!__traits(isRef, z))
But it is a bit ugly.
Another option is to use a variadic template, verify the parameters
match the lvalue version, and then use some testing on the parameter
tuple. Or use a mixin based on the original function.
Probably the mixin could work something like:
mixin(disableNonRef!lval_only);
-Steve
More information about the Digitalmars-d
mailing list