www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Variadic Struct Parameter

reply Jonathan Levi <catanscout gmail.com> writes:
Why is this not working?

```
struct S {
     int x;
     string y;
}

void fun(S s ...) {
     writeln(s);
}

void main() {
     fun(S(5,"hi"));
     fun(5,"hi");
}
```

Why does `fun` compile if calling it does not?
Jan 12
parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Tuesday, 12 January 2021 at 17:26:15 UTC, Jonathan Levi wrote:
 Why is this not working?

 ```
 struct S {
     int x;
     string y;
 }

 void fun(S s ...) {
This is intended for arrays and classes, not structs. Using ... for something other than arrays and c
     fun(S(5,"hi"));
That one should compile...
     fun(5,"hi");
and the second one not. It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
Jan 12
next sibling parent reply Jonathan Levi <catanscout gmail.com> writes:
On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
 It's obvious why arrays work, it's the primary use case. I have 
 no idea why classes are allowed. That classes are allowed, but 
 structs are not, makes no sense to me.
I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering). But why does this compile? ``` struct S {/*...*/} void fun(S s...) {/*...*/} ``` If structs do not work as variadic parameters, why does `fun` still compile?
Jan 12
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/12/21 10:44 AM, Jonathan Levi wrote:

 why does `fun` still compile?
I'm not familiar with that particular syntax, I don't know why it compiles, and I don't know why structs are different. :) However, it looks very much like the following *slice* syntax: void fun(S[] s...) { writeln(s); } In that case, the function receives a slice (to an array on the stack; so, do not keep a reference to it). Is that what you want? Ali
Jan 12
prev sibling next sibling parent reply ryuukk_ <ryuukk_ gmail.com> writes:
On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
 On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
 It's obvious why arrays work, it's the primary use case. I 
 have no idea why classes are allowed. That classes are 
 allowed, but structs are not, makes no sense to me.
I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering). But why does this compile? ``` struct S {/*...*/} void fun(S s...) {/*...*/} ``` If structs do not work as variadic parameters, why does `fun` still compile?
you can do this: ``` import std.stdio; import core.internal.moving; import core.memory; void main() { auto a = Data(1); auto b = Data(2); auto c = Data(3); hello(a, b, c); } void hello(Data...)(Data args) { writeln("n: ", args.length); foreach (data; args) writeln(data); } struct Data { int a = 5; } ``` this works fine: https://run.dlang.io/is/YA9syo
Jan 12
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/12/21 2:49 PM, ryuukk_ wrote:
 On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
 On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
 It's obvious why arrays work, it's the primary use case. I have no 
 idea why classes are allowed. That classes are allowed, but structs 
 are not, makes no sense to me.
I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering). But why does this compile? ``` struct S {/*...*/} void fun(S s...) {/*...*/} ``` If structs do not work as variadic parameters, why does `fun` still compile?
you can do this: ``` import std.stdio; import core.internal.moving; import core.memory; void main() {     auto a = Data(1);     auto b = Data(2);     auto c = Data(3);     hello(a, b, c); } void hello(Data...)(Data args)
this is a template parameter named 'Data' that supersedes the module-level type named 'Data'. Not the same thing. -Steve
Jan 12
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Tuesday, 12 January 2021 at 18:44:53 UTC, Jonathan Levi wrote:
 On Tuesday, 12 January 2021 at 17:46:14 UTC, Q. Schroll wrote:
 It's obvious why arrays work, it's the primary use case. I 
 have no idea why classes are allowed. That classes are 
 allowed, but structs are not, makes no sense to me.
I like the variadic feature for classes, but I wish it worked for structs as well, given that structs are value types on the stack anyway, the same assembly could have either signature (assuming matching argument/struct ordering). But why does this compile? ``` struct S {/*...*/} void fun(S s...) {/*...*/} ``` If structs do not work as variadic parameters, why does `fun` still compile?
Because D does allow you to specify things that have no effect. People sometimes complain about this as nonsense, but it has its merits in meta-programming: void fun(T)(T t...) { } Here, if T is a class or array type (including static arrays, btw), the dots have an effect, otherwise not. It would be unnecessary to require a split on the basis what T is.
Jan 12
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/12/21 12:46 PM, Q. Schroll wrote:
 On Tuesday, 12 January 2021 at 17:26:15 UTC, Jonathan Levi wrote:
 Why is this not working?

 ```
 struct S {
     int x;
     string y;
 }

 void fun(S s ...) {
This is intended for arrays and classes, not structs. Using ... for something other than arrays and c
     fun(S(5,"hi"));
That one should compile...
     fun(5,"hi");
and the second one not. It's obvious why arrays work, it's the primary use case. I have no idea why classes are allowed. That classes are allowed, but structs are not, makes no sense to me.
Originally, structs did not allow a constructor. I'm thinking probably when they got constructors, the (almost never-used) variadic form of class parameter passing did not get ported to structs. -Steve
Jan 12