Comment #0 by peter.alexander.au — 2013-01-21T12:50:45Z
It would be helpful if it were possible to alias partially specified templates. An example:
void foo(A, B)() {}
alias foo!int fooInt;
Currently this fails with "Error: template instance foo!(int) foo!(int) does not match template declaration foo(A, B)()".
However, if you write foo as:
template foo(A)
{
void foo(B)() {}
}
Then it works.
This would be useful because it would allow you to write things like:
alias equalRoR = equal!equal;
instead of having to write:
alias equalRoR = binaryFun!((a, b) => equal!equal(a, b));
Comment #1 by andrej.mitrovich — 2013-01-21T13:15:33Z
This can be implemented in the library, the last thing you want is for templates being partially instantiated when you pass too few arguments instead of getting an error.
Comment #2 by peter.alexander.au — 2013-01-21T15:11:58Z
(In reply to comment #1)
> This can be implemented in the library, the last thing you want is for
> templates being partially instantiated when you pass too few arguments instead
> of getting an error.
There will be no partial instantiation (what it that anyway?)
What I'm asking for is a rewrite from:
alias A = B!(x, y);
to
alias A = ((args...) => B!(x, y)(args)); // if this was valid syntax
when B has more than 2 non-default template parameters. The rest are determined using type deduction when A is invoked.
This is frustrating:
void foo(A, B)(A a, B b) {}
foo(1, 2); // OK
foo!(int)(1, 2); // OK
foo!(int, int)(1, 2); // OK
alias X = foo; // OK
alias Y = foo!(int); // ERROR
alias Z = foo!(int, int); // OK
Comment #3 by yebblies — 2013-01-21T20:19:02Z
Something like
alias A(T) = B!(x, T);
Is more likely and more flexible.
Expanding to:
template A(T)
{
alias A B!(x, T)
}
Comment #4 by peter.alexander.au — 2013-06-09T23:35:09Z
(In reply to comment #3)
> Something like
>
> alias A(T) = B!(x, T);
>
> Is more likely and more flexible.
See my use case, with your suggestions, this wouldn't work:
alias equalRoR = equal!equal;
An alternative suggestion, is to change how function templates are expanded. Currently we have:
void foo(A, B)(A a, B b)
expanding to
template foo(A, B)
{
void foo(A a, B b);
}
If instead, it expanded to:
template foo(A)
{
template foo(B)
{
void foo(A a, B b);
}
}
Then foo!int becomes a valid, alias-able symbol, which would solve the problem as well.
Comment #5 by monarchdodra — 2013-11-10T13:25:45Z
In reply to comment #3)
> Something like
>
> alias A(T) = B!(x, T);
>
> Is more likely and more flexible.
>
> Expanding to:
>
> template A(T)
> {
> alias A B!(x, T)
> }
This is now a done functionality :)
Comment #6 by monarchdodra — 2013-11-10T13:31:00Z
In reply to comment #4)
> (In reply to comment #3)
> > Something like
> >
> > alias A(T) = B!(x, T);
> >
> > Is more likely and more flexible.
>
> See my use case, with your suggestions, this wouldn't work:
>
> alias equalRoR = equal!equal;
>
> An alternative suggestion, is to change how function templates are expanded.
> Currently we have:
>
> void foo(A, B)(A a, B b)
>
> expanding to
>
> template foo(A, B)
> {
> void foo(A a, B b);
> }
>
> If instead, it expanded to:
>
> template foo(A)
> {
> template foo(B)
> {
> void foo(A a, B b);
> }
> }
>
> Then foo!int becomes a valid, alias-able symbol, which would solve the problem
> as well.
I think this would also come with its own problems:
For example, how would you tell apart full/partial, eg:
void foo(U)();
void foo(U, V)();
alias F = foo!int; //which one is this?
There's also some problems with constraints. It's difficult to do what you suggest if there is a constraint that depends on both A/B. At best, you can validate when the last parameter is specified.
Comment #7 by peter.alexander.au — 2013-11-10T13:58:24Z
(In reply to comment #6)
> In reply to comment #4)
> > (In reply to comment #3)
> > > Something like
> > >
> > > alias A(T) = B!(x, T);
> > >
> > > Is more likely and more flexible.
> >
> > See my use case, with your suggestions, this wouldn't work:
> >
> > alias equalRoR = equal!equal;
> >
> > An alternative suggestion, is to change how function templates are expanded.
> > Currently we have:
> >
> > void foo(A, B)(A a, B b)
> >
> > expanding to
> >
> > template foo(A, B)
> > {
> > void foo(A a, B b);
> > }
> >
> > If instead, it expanded to:
> >
> > template foo(A)
> > {
> > template foo(B)
> > {
> > void foo(A a, B b);
> > }
> > }
> >
> > Then foo!int becomes a valid, alias-able symbol, which would solve the problem
> > as well.
>
> I think this would also come with its own problems:
>
> For example, how would you tell apart full/partial, eg:
>
> void foo(U)();
> void foo(U, V)();
>
> alias F = foo!int; //which one is this?
This is no different than:
alias F = foo;
It matches the template, not the instantiation. See my rewrite suggestion.
> There's also some problems with constraints. It's difficult to do what you
> suggest if there is a constraint that depends on both A/B. At best, you can
> validate when the last parameter is specified.
It's the same as aliasing a template -- you validate only when it is used.