Jump to page: 1 2
Thread overview
Can someone explain this error?
Sep 23, 2008
Sean Kelly
Sep 23, 2008
Sean Kelly
Sep 24, 2008
Sean Kelly
Sep 24, 2008
Bill Baxter
Sep 24, 2008
Sean Kelly
Sep 23, 2008
Bill Baxter
Sep 24, 2008
BCS
Sep 24, 2008
Bill Baxter
Sep 24, 2008
Sean Kelly
Sep 24, 2008
Bill Baxter
Sep 25, 2008
Sergey Gromov
September 23, 2008
    class C
    {
        this() {}
        this( int x, int y ) {}
    }

    void main()
    {
        auto c = alloc!(C);
        auto d = alloc!(C)( 1, 2 );
    }

    T alloc(T, Params ...)( Params params )
    {
        return new T( params );
    }

$ dmd test
test.d(10): Error: expected 0 arguments, not 2
September 23, 2008
On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean@invisibleduck.org> wrote:
>    class C
>    {
>        this() {}
>        this( int x, int y ) {}
>    }
>
>    void main()
>    {
>        auto c = alloc!(C);
>        auto d = alloc!(C)( 1, 2 );
>    }
>
>    T alloc(T, Params ...)( Params params )
>    {
>        return new T( params );
>    }
>
> $ dmd test
> test.d(10): Error: expected 0 arguments, not 2
>

You cannot partially specify a template.  alloc!(C) means that Params... is the empty tuple: hence, 0 arguments expected.

template alloc(T)
{
    T alloc(Params ...)( Params params )
    {
        return new T( params );
    }
}

does the trick, but requires you to call it with empty parens in the
0-param case (like "alloc!(C)()").
September 23, 2008
On Wed, Sep 24, 2008 at 8:40 AM, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
> On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean@invisibleduck.org> wrote:
>>    class C
>>    {
>>        this() {}
>>        this( int x, int y ) {}
>>    }
>>
>>    void main()
>>    {
>>        auto c = alloc!(C);
>>        auto d = alloc!(C)( 1, 2 );
>>    }
>>
>>    T alloc(T, Params ...)( Params params )
>>    {
>>        return new T( params );
>>    }
>>
>> $ dmd test
>> test.d(10): Error: expected 0 arguments, not 2
>>
>
> You cannot partially specify a template.  alloc!(C) means that Params... is the empty tuple: hence, 0 arguments expected.
>
> template alloc(T)
> {
>    T alloc(Params ...)( Params params )
>    {
>        return new T( params );
>    }
> }
>
> does the trick, but requires you to call it with empty parens in the
> 0-param case (like "alloc!(C)()").

Ah, that works now?  Good to know.  At some point that wasn't working
unless you did the full alloc!(C).alloc(params).

--bb
September 23, 2008
== Quote from Jarrett Billingsley (jarrett.billingsley@gmail.com)'s article
> On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> >    class C
> >    {
> >        this() {}
> >        this( int x, int y ) {}
> >    }
> >
> >    void main()
> >    {
> >        auto c = alloc!(C);
> >        auto d = alloc!(C)( 1, 2 );
> >    }
> >
> >    T alloc(T, Params ...)( Params params )
> >    {
> >        return new T( params );
> >    }
> >
> > $ dmd test
> > test.d(10): Error: expected 0 arguments, not 2
> >
> You cannot partially specify a template.  alloc!(C) means that
> Params... is the empty tuple: hence, 0 arguments expected.
> template alloc(T)
> {
>     T alloc(Params ...)( Params params )
>     {
>         return new T( params );
>     }
> }
> does the trick, but requires you to call it with empty parens in the
> 0-param case (like "alloc!(C)()").

I'm pretty sure it's possible to partially specify a template.  Consider:

    void main()
    {
        fn!(int)( 5 );
    }

    void fn(A, B)( B b ) {}

This works just fine, but if I change the function declaration to:

    void fn(A, B ...)( B b ) {}

it fails.  Are variadic templates a special case?


Sean
September 24, 2008
On Wed, Sep 24, 2008 at 8:26 AM, Sean Kelly <sean@invisibleduck.org> wrote:
>    class C
>    {
>        this() {}
>        this( int x, int y ) {}
>    }
>
>    void main()
>    {
>        auto c = alloc!(C);
>        auto d = alloc!(C)( 1, 2 );
>    }
>
>    T alloc(T, Params ...)( Params params )
>    {
>        return new T( params );
>    }
>
> $ dmd test
> test.d(10): Error: expected 0 arguments, not 2
>

This is the thing Walter made work in D2 but not D1.
  http://d.puremagic.com/issues/show_bug.cgi?id=493

You can sorta work around it by using nested templates. Then you can get a calling syntax like

  alloc!(C).D1_4ever;
  alloc!(C).D1_4ever(1,2);

--bb
September 24, 2008
Reply to Bill,


> Ah, that works now?  Good to know.  At some point that wasn't working
> unless you did the full alloc!(C).alloc(params).
> 
> --bb
> 

IIRC the full form doesn't work any more. If the shortcut form is allowed then the first alloc takes all the way to the inner function.


September 24, 2008
== Quote from Bill Baxter (wbaxter@gmail.com)'s article
> On Wed, Sep 24, 2008 at 8:26 AM, Sean Kelly <sean@invisibleduck.org> wrote:
> >    class C
> >    {
> >        this() {}
> >        this( int x, int y ) {}
> >    }
> >
> >    void main()
> >    {
> >        auto c = alloc!(C);
> >        auto d = alloc!(C)( 1, 2 );
> >    }
> >
> >    T alloc(T, Params ...)( Params params )
> >    {
> >        return new T( params );
> >    }
> >
> > $ dmd test
> > test.d(10): Error: expected 0 arguments, not 2
> >
> This is the thing Walter made work in D2 but not D1.
>   http://d.puremagic.com/issues/show_bug.cgi?id=493

Hm.  It was D2 that gave me the error.


Sean
September 24, 2008
On Tue, Sep 23, 2008 at 7:56 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> == Quote from Jarrett Billingsley (jarrett.billingsley@gmail.com)'s article
>> On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean@invisibleduck.org> wrote:
>> >    class C
>> >    {
>> >        this() {}
>> >        this( int x, int y ) {}
>> >    }
>> >
>> >    void main()
>> >    {
>> >        auto c = alloc!(C);
>> >        auto d = alloc!(C)( 1, 2 );
>> >    }
>> >
>> >    T alloc(T, Params ...)( Params params )
>> >    {
>> >        return new T( params );
>> >    }
>> >
>> > $ dmd test
>> > test.d(10): Error: expected 0 arguments, not 2
>> >
>> You cannot partially specify a template.  alloc!(C) means that
>> Params... is the empty tuple: hence, 0 arguments expected.
>> template alloc(T)
>> {
>>     T alloc(Params ...)( Params params )
>>     {
>>         return new T( params );
>>     }
>> }
>> does the trick, but requires you to call it with empty parens in the
>> 0-param case (like "alloc!(C)()").
>
> I'm pretty sure it's possible to partially specify a template.  Consider:
>
>    void main()
>    {
>        fn!(int)( 5 );
>    }
>
>    void fn(A, B)( B b ) {}
>
> This works just fine, but if I change the function declaration to:
>
>    void fn(A, B ...)( B b ) {}
>
> it fails.  Are variadic templates a special case?
>
>
> Sean
>

Uh, what compiler are you using?  That fails for me (1.034).
September 24, 2008
On Wed, Sep 24, 2008 at 9:08 AM, Sean Kelly <sean@invisibleduck.org> wrote:
> == Quote from Bill Baxter (wbaxter@gmail.com)'s article
>> On Wed, Sep 24, 2008 at 8:26 AM, Sean Kelly <sean@invisibleduck.org> wrote:
>> >    class C
>> >    {
>> >        this() {}
>> >        this( int x, int y ) {}
>> >    }
>> >
>> >    void main()
>> >    {
>> >        auto c = alloc!(C);
>> >        auto d = alloc!(C)( 1, 2 );
>> >    }
>> >
>> >    T alloc(T, Params ...)( Params params )
>> >    {
>> >        return new T( params );
>> >    }
>> >
>> > $ dmd test
>> > test.d(10): Error: expected 0 arguments, not 2
>> >
>> This is the thing Walter made work in D2 but not D1.
>>   http://d.puremagic.com/issues/show_bug.cgi?id=493
>
> Hm.  It was D2 that gave me the error.

Odd.  This template is in std.algorithm for instance:

    Ranges[0] filter(alias pred, Ranges...)(Ranges rs) { ... }

and called using

   filter!("a<10")(a);

in the unittests.

Here's the full code:
----------------------------------------------------------------------
Ranges[0] filter(alias pred, Ranges...)(Ranges rs)
{
    alias unaryFun!(pred) fun;
    typeof(return) result;
    // Accumulate
    foreach (i, range; rs[0 .. $]) // all inputs
    {
        foreach (it; begin(range) .. end(range)) // current input
        {
            if (fun(*it)) result ~= *it;
        }
    }
    return result;
}

unittest
{
    int[] a = [ 3, 4 ];
    auto r = filter!("a > 3")(a);
    assert(r == [ 4 ]);

    a = [ 1, 22, 3, 42, 5 ];
    auto under10 = filter!("a < 10")(a);
    assert(under10 == [1, 3, 5]);
}
----------------------------------------------------
September 24, 2008
== Quote from Jarrett Billingsley (jarrett.billingsley@gmail.com)'s article
> On Tue, Sep 23, 2008 at 7:56 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> > == Quote from Jarrett Billingsley (jarrett.billingsley@gmail.com)'s article
> >> On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> >> >    class C
> >> >    {
> >> >        this() {}
> >> >        this( int x, int y ) {}
> >> >    }
> >> >
> >> >    void main()
> >> >    {
> >> >        auto c = alloc!(C);
> >> >        auto d = alloc!(C)( 1, 2 );
> >> >    }
> >> >
> >> >    T alloc(T, Params ...)( Params params )
> >> >    {
> >> >        return new T( params );
> >> >    }
> >> >
> >> > $ dmd test
> >> > test.d(10): Error: expected 0 arguments, not 2
> >> >
> >> You cannot partially specify a template.  alloc!(C) means that
> >> Params... is the empty tuple: hence, 0 arguments expected.
> >> template alloc(T)
> >> {
> >>     T alloc(Params ...)( Params params )
> >>     {
> >>         return new T( params );
> >>     }
> >> }
> >> does the trick, but requires you to call it with empty parens in the
> >> 0-param case (like "alloc!(C)()").
> >
> > I'm pretty sure it's possible to partially specify a template.  Consider:
> >
> >    void main()
> >    {
> >        fn!(int)( 5 );
> >    }
> >
> >    void fn(A, B)( B b ) {}
> >
> > This works just fine, but if I change the function declaration to:
> >
> >    void fn(A, B ...)( B b ) {}
> >
> > it fails.  Are variadic templates a special case?
> >
> Uh, what compiler are you using?  That fails for me (1.034).

2.019


Sean
« First   ‹ Prev
1 2