Thread overview
[Issue 8687] New: Variadic templates do not work properly with default arguments
Sep 18, 2012
Andrej Mitrovic
Jun 22, 2013
Andrej Mitrovic
Jun 30, 2013
Andrej Mitrovic
Oct 07, 2013
Walter Bright
September 18, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8687

           Summary: Variadic templates do not work properly with default
                    arguments
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrej.mitrovich@gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-09-18 09:09:36 PDT ---
A simplified version of std.range.lockstep:

auto newLockstep(Args...)(Args args, StoppingPolicy stoppingPolicy =
StoppingPolicy.shortest)
{
     // ...
}

However it doesn't work:

foreach (x, y; newLockstep([1, 2], [1, 2])) { }

test.d(32): Error: template test.newLockstep does not match any
function template declaration
test.d(14): Error: template test.newLockstep(Args...) if
(allSatisfy!(isInputRange,staticMap!(Unqual,Args))) cannot deduce
template function from argument types !()(int[],int[])

Passing an argument in place of the default explicitly does work:
foreach (x, y; newLockstep([1, 2], [1, 2], StoppingPolicy.shortest)) { }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=8687


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |k.hara.pg@gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-06-22 00:22:18 PDT ---
A better use-case is:

void foo(Args...)(Args args, string file = __FILE__, size_t line = __LINE__)
{
}

This would allow us to construct error messages with file + line but without creating template bloat because file and line usually have to become template value arguments in order to support variadic arguments. IOW the above currently has to be:

void foo(string file = __FILE__, size_t line = __LINE__, Args...)(Args args)
{
}

But this creates too much template bloat. I've seen other people ask for this feature, I think schveiguy (Steven Schveighoffer) mentioned it as well.

Here's an example use-case, where an enforce-style function can take a format string and avoid the need to call format() explicitly from the call-site:

/** Similar to $(D enforce), except it can take a formatting string as the
second argument. */
T require(T, Args...)
    (T value, lazy Args args, string file = __FILE__, size_t line = __LINE__)
{
    static if (Args.length)
        string msg = Args.length > 1 ? format(args[0], args[1 .. $]) :
text(args);
    else
        enum msg = "requirement failed.";

    if (!value)
        throw new Exception(msg, file, line);

    return value;
}

unittest
{
    string file = "foo.d";
    require(file.exists, "File '%s' does not exist.", file);
}

Currently this won't compile unless you make file and line compile-time arguments.

@Kenji: Do you think it's possible to implement this without a big disruption
(e.g. code breakage)?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=8687


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice


--- Comment #2 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-06-30 10:19:58 PDT ---
Please note that in 2.063 the compiler now ICEs on this unsupported feature:

-----
void foo(T...)(T args, string file = __FILE__) { }

void main()
{
    foo();
}
-----

> Assertion failure: 'index < dim' on line 462 in file 'root\root.h'

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 07, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=8687


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|ice                         |
                 CC|                            |bugzilla@digitalmars.com


--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2013-10-06 23:41:37 PDT ---
(In reply to comment #2)
> Please note that in 2.063 the compiler now ICEs on this unsupported feature:
> 
> -----
> void foo(T...)(T args, string file = __FILE__) { }
> 
> void main()
> {
>     foo();
> }
> -----
> 
> > Assertion failure: 'index < dim' on line 462 in file 'root\root.h'

With 2.064 head, produces:

test.d(5): Error: template test.foo does not match any function template
declaration. Candidates are:
test.d(1):        test.foo(T...)(T args, string file = __FILE__)
test.d(5): Error: template test.foo(T...)(T args, string file = __FILE__)
cannot deduce template function from argument types !()()

Removed ice keyword.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------