digitalmars.D.learn - Can someone explain this error?
- Sean Kelly (16/16) Sep 23 2008 class C
- Jarrett Billingsley (12/28) Sep 23 2008 You cannot partially specify a template. alloc!(C) means that
- Sean Kelly (11/43) Sep 23 2008 I'm pretty sure it's possible to partially specify a template. Consider...
- Jarrett Billingsley (2/45) Sep 23 2008 Uh, what compiler are you using? That fails for me (1.034).
- Sean Kelly (3/54) Sep 23 2008 2.019
- Jarrett Billingsley (2/5) Sep 23 2008 I suppose that would have been nice to know in the first place :|
- Bill Baxter (6/23) Sep 23 2008 It seems all Andrei's usages of the feature in std.algorithm have an
- Sean Kelly (9/33) Sep 24 2008 No. Weird, huh?
- Bill Baxter (5/37) Sep 23 2008 Ah, that works now? Good to know. At some point that wasn't working
- BCS (3/8) Sep 23 2008 IIRC the full form doesn't work any more. If the shortcut form is allowe...
- Bill Baxter (8/24) Sep 23 2008 This is the thing Walter made work in D2 but not D1.
- Sean Kelly (3/26) Sep 23 2008 Hm. It was D2 that gave me the error.
- Bill Baxter (32/57) Sep 23 2008 Odd. This template is in std.algorithm for instance:
- Sergey Gromov (33/52) Sep 25 2008 I dug this case a bit more in 2.019. First of all, it's possible to
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
Sep 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 2You 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)()").
Sep 23 2008
== Quote from Jarrett Billingsley (jarrett.billingsley gmail.com)'s articleOn Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean invisibleduck.org> wrote: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? Seanclass 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 2You 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)()").
Sep 23 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 articleUh, what compiler are you using? That fails for me (1.034).On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean invisibleduck.org> wrote: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? Seanclass 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 2You 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)()").
Sep 23 2008
== Quote from Jarrett Billingsley (jarrett.billingsley gmail.com)'s articleOn Tue, Sep 23, 2008 at 7:56 PM, Sean Kelly <sean invisibleduck.org> wrote:2.019 Sean== Quote from Jarrett Billingsley (jarrett.billingsley gmail.com)'s articleUh, what compiler are you using? That fails for me (1.034).On Tue, Sep 23, 2008 at 7:26 PM, Sean Kelly <sean invisibleduck.org> wrote: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?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 2You 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)()").
Sep 23 2008
On Tue, Sep 23, 2008 at 8:23 PM, Sean Kelly <sean invisibleduck.org> wrote:== Quote from Jarrett Billingsley (jarrett.billingsley gmail.com)'s articleI suppose that would have been nice to know in the first place :|Uh, what compiler are you using? That fails for me (1.034).2.019
Sep 23 2008
It seems all Andrei's usages of the feature in std.algorithm have an alias parameter as the first, followed by the variadic. So maybe this is just a code path in the compiler that hasn't been tickled previously. Does your code work if you make the first param an alias? --bb2.019I'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).
Sep 23 2008
Bill Baxter wrote:No. Weird, huh? void main() { int x; fn!(x)( 5 ); } void fn(alias a, B ...)( B b ) {} SeanIt seems all Andrei's usages of the feature in std.algorithm have an alias parameter as the first, followed by the variadic. So maybe this is just a code path in the compiler that hasn't been tickled previously. Does your code work if you make the first param an alias?2.019I'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).
Sep 24 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:Ah, that works now? Good to know. At some point that wasn't working unless you did the full alloc!(C).alloc(params). --bbclass 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 2You 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)()").
Sep 23 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). --bbIIRC 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.
Sep 23 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 2This 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
Sep 23 2008
== Quote from Bill Baxter (wbaxter gmail.com)'s articleOn Wed, Sep 24, 2008 at 8:26 AM, Sean Kelly <sean invisibleduck.org> wrote:Hm. It was D2 that gave me the error. Seanclass 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 2This is the thing Walter made work in D2 but not D1. http://d.puremagic.com/issues/show_bug.cgi?id=493
Sep 23 2008
On Wed, Sep 24, 2008 at 9:08 AM, Sean Kelly <sean invisibleduck.org> wrote:== Quote from Bill Baxter (wbaxter gmail.com)'s articleOdd. 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]); } ----------------------------------------------------On Wed, Sep 24, 2008 at 8:26 AM, Sean Kelly <sean invisibleduck.org> wrote:Hm. It was D2 that gave me the error.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 2This is the thing Walter made work in D2 but not D1. http://d.puremagic.com/issues/show_bug.cgi?id=493
Sep 23 2008
In article <gbbtue$1uam$1 digitalmars.com>, sean invisibleduck.org says...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 2I dug this case a bit more in 2.019. First of all, it's possible to make it work for non-zero argument count by making a single change in the template body: T alloc(T, Params ...)( Params params ) { cast(void) params; return new T( params ); } though it stops accepting zero arguments because "tuple has no effect in expression (tuple())". The weirdest part is when you try to access number of arguments in the tuple: void main() { auto d = alloc!(C)( 1, 2 ); } T alloc(T, Params ...)( Params params ) { cast(void) params; pragma( msg, Params.length.stringof ); return new T( params ); } when compiling, prints: 0u 2u but without the cast: 0u test.d(12): Error: expected 0 arguments, not 2 So it instantiates the template once, check whether the tuple argument is explicitly used inside the template body, then instantiates it again with number of arguments depending on the previous instantiation. Looks to me like a dirty hack in the compiler.
Sep 25 2008