March 08, 2018
Is using

https://dlang.org/changelog/2.079.0.html#default_after_variadic

for instance as

void show(Args...)(Args args,
                   string file = __FILE__,
                   uint line = __LINE__,
                   string fun = __FUNCTION__)
    if (Args.length >= 1)
{
    ...
}

preferred over previous usage

template show(Args...)
    if (Args.length >= 1)
{
    void show(string file = __FILE__,
              uint line = __LINE__,
              string fun = __FUNCTION__)
    {
        ...
    }
}

or are the two version equally good in terms of run-time, compile-time and (lack of) template symbol bloatedness?

See also

https://github.com/nordlow/phobos-next/blob/master/src/dbgio.d#L53
March 08, 2018
On Thursday, March 08, 2018 08:36:09 Nordlöw via Digitalmars-d-learn wrote:
> Is using
>
> https://dlang.org/changelog/2.079.0.html#default_after_variadic
>
> for instance as
>
> void show(Args...)(Args args,
>                     string file = __FILE__,
>                     uint line = __LINE__,
>                     string fun = __FUNCTION__)
>      if (Args.length >= 1)
> {
>      ...
> }
>
> preferred over previous usage
>
> template show(Args...)
>      if (Args.length >= 1)
> {
>      void show(string file = __FILE__,
>                uint line = __LINE__,
>                string fun = __FUNCTION__)
>      {
>          ...
>      }
> }
>
> or are the two version equally good in terms of run-time, compile-time and (lack of) template symbol bloatedness?
>
> See also
>
> https://github.com/nordlow/phobos-next/blob/master/src/dbgio.d#L53

Well, the first one works with IFTI, whereas the second one does not, because the template arguments are not use in the function. So, you can just call the first one, whereas the second one will have to be explicitly instantiated in order to be called. And the second one has no runtime arguments corresponding to the template arguments, meaning that the two examples are really quite different. If what you meant was really

template show(Args...)
     if (Args.length >= 1)
{
     void show(Args args,
               string file = __FILE__,
               uint line = __LINE__,
               string fun = __FUNCTION__)
     {
         ...
     }
}

then that's basically identical to the first template, because that's what the first template gets lowered to. Directly templatizing a function or type is just a shortcut.

The big thing that you want to avoid doing is having the file and line number be template arguments rather than function arguments, because then you get a different template instantiation for each combination of file and line number, meaning that in practice, you're going to get a different instantiation of the function template every time you call it, which is definitely not good. However, now that it's been fixed so that you can have default arguments after a variadic template argument, there's really no need to do that, whereas previously, stuff like std.logger pretty much had to.

- Jonathan M Davis