Parameter-less templates?

monarch_dodra monarchdodra at gmail.com
Mon Aug 12 12:03:39 PDT 2013


D has introduced a pretty cool tool: templates. These are 
basically namespaces that can be instantiated by a type/alias. 
Mixing with them the notion of "eponymous" allows to do some 
seriously cool things with them.

One of the things I find strange though is that they *must* be 
parameterized. This limitation seems entirely artificial to me. 
Why not allow templates without parameters, just the same way 
some functions aren't parameterized. There are useful use-cases 
for this:
* Simple creation of namespaces (as opposed to non-contructible 
struct/classes)
* Allows creating private helpers, without polluting the rest of 
the module (private functions are still callable by other 
functions in the module).

So... yeah, why don't we have this?

--------

Related: I have encountered this problem, and I can't seem to 
work around it; *other* than non-parameterized templates. 
Basically, I have this pred function, we'll call it "foo". This 
pred function can itself be parameterized to take its own 
(optional) pred. This basically allows:
foo(a, b)
or
foo!pred(a, b)

This is "traditionally" solved by doing:
void foo(A, B)(A a, B b);
void foo(alias pred, A, B)(A a, B b);

Here is the kicker though: "foo" is itself a pred. This means 
that I *need* to be able to pass "foo!pred" as a predicate. This 
does not work, as "foo!pred" is nothing: The compiler doesn't 
know what you are talking about, as the parameters A and B are 
missing. This is usually solved by a template:

template foo(alias pred)
{
     void foo(A, B)(A a, B b);
}

This works.... *however* the presence of the "void foo(A, B)(A a, 
B b);" confuses the crap out of the compiler:
foo(a, b); //OK
alias PRED = foo!"hello";
PRED(a, b); //OK

BUT:
foo!"hello"(a, b); //Error:
Error: template hello.foo does not match any function template 
declaration. Candidates are:
hello.foo(R1, R2)(R1 r1, R2 r2)
hello.foo(alias pred)
Error: template hello.foo(R1, R2)(R1 r1, R2 r2) cannot deduce 
template function from argument types !("hello")(int, int)
Error: template instance foo!"hello" errors instantiating template

So... how to make this work? AFAIK, non-parameterized templates 
should solve it. Or is it just a compiler issue?

FYI: This is a problem present in Phobos. You can use:
"equal!equal(RoR1, RoR2)"
To compare two ranges of ranges. equal!equal gets instanciated, 
because the args are present to "finish" the missing R1/R2 args 
after pred.

However, this neat trick stop there:
"equal!(equal!equal)(RoRoR1, RoRoR2)"
This time, this does not work, as the compiler can't resolve the 
predicate.

I'd like to solve this. IMO "equal!equal" is one of the neatest 
"1-word" in D, and I want to make sure it works as one would 
expect it to.

--------

So: Any workaround recommendations? Alternatives? Thoughts on 
parameter-less templates (regardless of my issue)?


More information about the Digitalmars-d mailing list