[Issue 24629] New: Allow more than 1 set of template parameters
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Jun 25 16:10:16 UTC 2024
https://issues.dlang.org/show_bug.cgi?id=24629
Issue ID: 24629
Summary: Allow more than 1 set of template parameters
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: qs.il.paperinik at gmail.com
Apart from a `template` template, templates can be defined by giving the
construct template parameters, e.g. `class C(T)`, `void f(T)(T x)`, `enum
isConst(T) = …`, `alias Unshared(T) = …`, etc.
Those are equivalent to a `template` template with the respective construct
with the same name inside of it.
Why only allow one level of nesting? There is no good reason not to allow for
multiple nesting levels:
```d
void f(T)(U)(T t, U u) { … }
```
would be lowered to:
```d
template f(T)
{
template f(U)
{
void f(T t, U u) { … }
}
}
```
UFCS and IFTI work in a specific way with nested templates: Template arguments
can be inferred for the innermost `template`. In the example, that would mean
that callers _must_ provide `T` and the compiler can infer `U`.
Example uses cases can be merging `opAssign` and `opOpAssign`:
```d
struct S
{
alias opAssign = opOpAssign!"";
template opOpAssign(string op)
{
auto opOpAssign(R)(R rhs) { … }
}
}
```
the latter could be:
```d
auto opOpAssign(string op)(R)(R rhs) { … }
```
Note that in D, a set of template arguments can only contain one sequence
argument. When more are needed, nested templates are necessary.
I have encountered a case where 3 sets of template arguments would be useful:
- The uppermost level is a customization point (one provides a boolean); the
module exposes two aliases, one for the `true` and one for the `false`
instance. Those are almost identical and implementing that twice makes no
sense.
- The next level is any number of lambdas
- The innermost level takes the types of the arguments (which are usually
inferred).
Using that, instead of:
```d
alias matchByType = matchByTypeImpl!false;
alias matchByTypeExact = matchByTypeImpl!true;
private template matchByTypeImpl(bool exact)
{
template matchByTypeImpl(fs...)
{
auto ref matchByTypeImpl(T)(auto ref T x)
{
…
}
}
}
```
I could write:
```d
alias matchByType = matchByTypeImpl!false;
alias matchByTypeExact = matchByTypeImpl!true;
private template matchByTypeImpl(bool exact)(fs...)(T)(auto ref T x)
{
…
}
```
--
More information about the Digitalmars-d-bugs
mailing list