digitalmars.D.learn - Can someone explain this error?
- Sean Kelly <sean invisibleduck.org> Sep 23 2008
- "Jarrett Billingsley" <jarrett.billingsley gmail.com> Sep 23 2008
- Sean Kelly <sean invisibleduck.org> Sep 23 2008
- Sean Kelly <sean invisibleduck.org> Sep 23 2008
- Sean Kelly <sean invisibleduck.org> Sep 24 2008
- "Bill Baxter" <wbaxter gmail.com> Sep 23 2008
- BCS <ao pathlink.com> Sep 23 2008
- "Bill Baxter" <wbaxter gmail.com> Sep 23 2008
- Sean Kelly <sean invisibleduck.org> Sep 23 2008
- "Jarrett Billingsley" <jarrett.billingsley gmail.com> Sep 23 2008
- "Bill Baxter" <wbaxter gmail.com> Sep 23 2008
- "Jarrett Billingsley" <jarrett.billingsley gmail.com> Sep 23 2008
- "Bill Baxter" <wbaxter gmail.com> Sep 23 2008
- Sergey Gromov <snake.scaly gmail.com> Sep 25 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
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 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)()").
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: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
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
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:== Quote from Jarrett Billingsley (jarrett.billingsley gmail.com)'s articleOn 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
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?
2.019 Sean
Sep 23 2008
Bill Baxter 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?
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?
No. Weird, huh? void main() { int x; fn!(x)( 5 ); } void fn(alias a, B ...)( B b ) {} Sean
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: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
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). --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.
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 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
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: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
http://d.puremagic.com/issues/show_bug.cgi?id=493
Hm. It was D2 that gave me the error. Sean
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 articleOn 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
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).
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 articleOn 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
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]); } ----------------------------------------------------
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 articleUh, what compiler are you using? That fails for me (1.034).
2.019
I suppose that would have been nice to know in the first place :|
Sep 23 2008
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?
2.019
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? --bb
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 2
I 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









Sean Kelly <sean invisibleduck.org> 