www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template sequence parameter and default value

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
What is the best way to emulate a default value for template 
sequence parameter of a function?

I want something like this:
```d
void foo(MODULES... = __MODULE__)() {}

// these should work:
foo!(module1, module2);
foo!(module1);
foo();          // this should use current module (__MODULE__) 
according to default value
```
Jan 26 2022
next sibling parent reply Jaime <benjamin.i.mccann gmail.com> writes:
On Thursday, 27 January 2022 at 02:49:22 UTC, Andrey Zherikov 
wrote:
 What is the best way to emulate a default value for template 
 sequence parameter of a function?

 I want something like this:
 ```d
 void foo(MODULES... = __MODULE__)() {}

 // these should work:
 foo!(module1, module2);
 foo!(module1);
 foo();          // this should use current module (__MODULE__) 
 according to default value
 ```
You can accomplish this by heading off the template sequence parameter with several default template parameters. If you need them all under one name, you can recombine them in the function body with std.meta.AliasSeq, the effective "kind" of a template sequence parameter. Example: ```d void foo(string FirstModule = __MODULE__, RestModules...)() { alias Modules = AliasSeq!(FirstModule, RestModules); // things } // foo!(module1, module2) => alias Modules = (module1, module2) // foo!() => alias Modules = (__MODULE__) ```
Jan 26 2022
parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Thursday, 27 January 2022 at 03:19:59 UTC, Jaime wrote:
 You can accomplish this by heading off the template sequence 
 parameter with several default template parameters. If you need 
 them all under one name, you can recombine them in the function 
 body with std.meta.AliasSeq, the effective "kind" of a template 
 sequence parameter.

 Example:

 ```d
 void foo(string FirstModule = __MODULE__, RestModules...)() {
     alias Modules = AliasSeq!(FirstModule, RestModules);
     // things
 }

 // foo!(module1, module2) => alias Modules = (module1, module2)
 // foo!() => alias Modules = (__MODULE__)
 ```
Unfortunately `string FirstModule` doesn't work if I specify the module: https://run.dlang.io/is/BZd0KB The closest solution I have is this: ```d void foo(MODULES...)() { writeln(MODULES.stringof); } alias foo(string MODULE = __MODULE__) = foo!(mixin(MODULE)); void main() { writeln(1); foo(); writeln(2); foo!(onlineapp); writeln(3); foo!(onlineapp,onlineapp); } ``` It prints this: ``` 1 tuple(module onlineapp) 2 tuple(module onlineapp) 3 tuple(module onlineapp, module onlineapp) ``` So is it possible to get rid of the alias?
Jan 27 2022
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/27/22 10:21 AM, Andrey Zherikov wrote:

 So is it possible to get rid of the alias?
I'm not sure it's worth the effort? Yours is a pretty straightforward solution. -Steve
Jan 27 2022
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/26/22 18:49, Andrey Zherikov wrote:

 I want something like this:
 ```d
 void foo(MODULES... = __MODULE__)() {}
Two other options: 1) void foo(MODULES_...)() { static if (MODULES_.length == 0) { import std.meta : AliasSeq; alias MODULES = AliasSeq!__MODULE__; } else { alias MODULES = MODULES_; } } 2) void foo(MODULES_...)() { } void foo() { return foo!__MODULE__; } Ali
Jan 27 2022