D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4167 - Template overrides with alias
Summary: Template overrides with alias
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-09 07:02 UTC by bearophile_hugs
Modified: 2021-03-17 13:47 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-05-09 07:02:05 UTC
This is an enhancement request, but I am not sure if this can be done, and even if it's doable I don't know if this is a good idea. If it's hard to implement or it's not a good idea you can close this.

This is correct D2 code that uses an alias to emulate a new override of function foo:


int foo(int x) {
    return 10;
}
int bar(int x, int y) {
    return 20;
}
alias bar foo;
void main() {
    int x1 = foo(1);      // OK
    int x2 = bar(2, 100); // OK
    int x3 = foo(3, 100); // OK
}



But similar code with templates doesn't work, and produces (dmd 2.043):
test.d(7): Error: alias test.Foo conflicts with template test.Foo(int x) at test.d(1)


template Foo(int x) {
    enum int Foo = 10;
}
template Bar(int x, int y) {
    enum int Bar = 10;
}
alias Bar Foo; // line 7, Error
void main() {
    int x1 = Foo!(1);      // OK
    int x2 = Bar!(2, 100); // OK
    int x3 = Foo!(3, 100); // Not OK
}



To do that I have to create a wrapper, this seems to work:

template Foo(int x) {
    enum int Foo = 10;
}
template Bar(int x, int y) {
    enum int Bar = 10;
}
template Foo(int x, int y) {
    enum int Foo = Bar!(x, y);
}
void main() {
    int x1 = Foo!(1);      // OK
    int x2 = Bar!(2, 100); // OK
    int x3 = Foo!(3, 100); // OK
}


Is it possible to change the compiler so an alias can be used to emulate template overloads?

I have asked on IRC and two persons have said that such usage of alias with templates can be a little confusing.

This usage of the alias can be seen useful for a simple form of Partial Template Application, similar to template currying:


import std.stdio: writeln;
import std.conv: to;
import std.algorithm: array, map;

template to_(Tout) {
    Tout to_(Tin)(Tin x) {
        return to!(Tout, Tin)(x);
    }
}
alias to to_; // Currently an error here
void main() {
    string[] data = ["1", "2", "3"];
    int[] arr = array(map!(to_!int)(data));
    writeln(to_!int("10"));
}


Currently the map! needs a full template specialization:
map!(to!(int, string))(data)

While the writeln can use half specialization:
writeln(to!int("10"));

Defining that to_ plus using an alias I can create a partial template.
Comment 1 Infiltrator 2014-03-18 22:51:24 UTC
Is there any particular reason that you need to override with alias?  The below works:

template Foo(int x) {
    enum int Foo = 10;
}
template Foo(int x, int y) {
    enum int Foo = 10;
}
void main() {
    int x1 = Foo!(1);      // OK
    int x2 = Foo!(2, 100); // OK
    int x3 = Foo!(3, 100); // OK
}
Comment 2 RazvanN 2021-03-17 13:47:49 UTC
The originally reported code compiles successfully with git head. Closing as fixed.