Is this a bug?

Steven Schveighoffer schveiguy at gmail.com
Tue Oct 16 13:09:34 UTC 2018


On 10/15/18 4:36 PM, Márcio Martins wrote:
> On Monday, 15 October 2018 at 16:46:34 UTC, Steven Schveighoffer wrote:
>> On 10/15/18 12:40 PM, Márcio Martins wrote:
>>> import std.stdio;
>>>
>>> void incx(T, Args...)(ref T t) {
>>>      ++t.x;
>>> }
>>>
>>> static struct Test(T) {
>>>      T x;
>>> }
>>>
>>> void main() {
>>>      Test!uint t;
>>>      t.incx();           // works
>>>      t.incx!();          // works
>>>      incx(t);            // works
>>>      t.incx!(1, 2, 3);   // what?
>>>      incx(t, 1, 2, 3);   // what?
>>>      writeln(t.x);
>>> }
>>>
>>>
>>> test.d(16): Error: template test.incx cannot deduce function from 
>>> argument types !(1, 2, 3)(Test!uint), candidates are:
>>> test.d(3):        test.incx(T, Args...)(ref T t)
>>
>> No, not a bug.
>>
>> I suspect you want this?
>>
>> void incx(Args..., T)(ref T t);
> 
> This doesn't seem to work, because:
> test.d(3): Error: template `test.incx(Args..., T)(ref T t)` template 
> tuple parameter must be last one

Hm... didn't realize that. It seems to me like an odd limitation, but I 
can see how it's ambiguous.

The solution is to double-template:

template incx(Args...)
{
    void incx(T)(ref T t)
    {
       ++t.x;
    }
}

> 
> Are you sure it's not a bug? It would be very un-intuitive otherwise, no?
> Considering that the declaration is legal, and that the template 
> parameter deduction works when Args.length == 0, but stops working when 
> Args.length > 0.

Not a bug, because when you explicitly specify template parameters, they 
are specified in left-to-right order.

You have incx(T, Args...)(ref T t)

t.incx!(1, 2, 3); // 1 => T (error), 2 => Args[0], 3 => Args[1]
incx(t, 1, 2, 3); // typeof(t) => T (uses IFTI), Args == empty tuple,
                   // 1, 2, 3 => extra runtime parameters that don't 
match anything?

-Steve


More information about the Digitalmars-d-learn mailing list