Thread overview
Template sequence parameter and default value
Jan 27, 2022
Andrey Zherikov
Jan 27, 2022
Jaime
Jan 27, 2022
Andrey Zherikov
Jan 27, 2022
Ali Çehreli
January 27, 2022

What is the best way to emulate a default value for template sequence parameter of a function?

I want something like this:

void foo(MODULES... = __MODULE__)() {}

// these should work:
foo!(module1, module2);
foo!(module1);
foo();          // this should use current module (__MODULE__) according to default value
January 27, 2022

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:

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:

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

// foo!(module1, module2) => alias Modules = (module1, module2)
// foo!() => alias Modules = (__MODULE__)
January 27, 2022

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:

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:

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?

January 27, 2022

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

January 27, 2022
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