Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 01, 2008 Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Is there a way to do something like this in D1 without resorting to function overloading?: void Foo(T : char, wchar, dchar)(T arg) {/*code*/} |
July 01, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:g4e7bg$20n8$1@digitalmars.com... > Is there a way to do something like this in D1 without resorting to function overloading?: > > void Foo(T : char, wchar, dchar)(T arg) {/*code*/} It's not perfect, but: void Foo(T)(T arg) { static assert(is(T == char) || is(T == wchar) || is(T == dchar), "T must be char, wchar, or dchar"); } D2 would let you put that in a template condition, but D1's stuck with a static assert. |
July 01, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Reply to Nick,
> Is there a way to do something like this in D1 without resorting to
> function overloading?:
>
> void Foo(T : char, wchar, dchar)(T arg) {/*code*/}
>
public template Foo(T: char) {alias Foo_dwc(T) Foo; }
public template Foo(T: wchar) {alias Foo_dwc(T) Foo; }
public template Foo(T: dchar) {alias Foo_dwc(T) Foo; }
private void Foo_dwc(T)(T arg) { ... }
|
July 01, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:g4e7em$2146$1@digitalmars.com... > "Nick Sabalausky" <a@a.a> wrote in message news:g4e7bg$20n8$1@digitalmars.com... >> Is there a way to do something like this in D1 without resorting to function overloading?: >> >> void Foo(T : char, wchar, dchar)(T arg) {/*code*/} > > It's not perfect, but: > > void Foo(T)(T arg) > { > static assert(is(T == char) || is(T == wchar) || is(T == dchar), "T > must be char, wchar, or dchar"); > } > > D2 would let you put that in a template condition, but D1's stuck with a static assert. > Yea, I had actually tried that. It technically works, but when the assert fails the compiler just gives you the file/line of the static assert itself, and doesn't give any indication of what file/line attempted the failed instantiation of Foo (which would be a nightmare to track down, particularly if Foo was in a library). |
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | "BCS" <ao@pathlink.com> wrote in message news:55391cb32eba48caa9a02d954116@news.digitalmars.com... > Reply to Nick, > >> Is there a way to do something like this in D1 without resorting to function overloading?: >> >> void Foo(T : char, wchar, dchar)(T arg) {/*code*/} >> > > public template Foo(T: char) {alias Foo_dwc(T) Foo; } > public template Foo(T: wchar) {alias Foo_dwc(T) Foo; } > public template Foo(T: dchar) {alias Foo_dwc(T) Foo; } > > private void Foo_dwc(T)(T arg) { ... } > > Failed to compile. Not sure if it's a problem with the technique, a typo, an existing compiler bug, or a previously fixed compiler bug. ----- start test1.d ----- public template Foo(T: char) {alias Foo_dwc(T) Foo; } public template Foo(T: wchar) {alias Foo_dwc(T) Foo; } public template Foo(T: dchar) {alias Foo_dwc(T) Foo; } private void Foo_dwc(T)(T arg) { } void main(char[][] args) { Foo('a'); } ----- end test1.d ----- ----- start compiler output: DMD win 1.029 ----- test1.d(1): semicolon expected to close alias declaration test1.d(1): no identifier for declarator Foo test1.d(2): semicolon expected to close alias declaration test1.d(2): no identifier for declarator Foo test1.d(3): semicolon expected to close alias declaration test1.d(3): no identifier for declarator Foo ----- end compiler output: DMD win 1.029 ----- Just for the hell of it, I tried changing all three "alias Foo_dwc(T) Foo;" to "alias Foo_dwc!(T) Foo;" (ie, added "!"): ----- start test2.d ----- public template Foo(T: char) {alias Foo_dwc!(T) Foo; } public template Foo(T: wchar) {alias Foo_dwc!(T) Foo; } public template Foo(T: dchar) {alias Foo_dwc!(T) Foo; } private void Foo_dwc(T)(T arg) { } void main(char[][] args) { Foo('a'); } ----- end test2.d ----- ----- start compiler output: DMD win 1.029 ----- test2.d(1): template test2.Foo(T : char) is not a function template test2.d(9): template test2.Foo(T : char) cannot deduce template function from argument types (char) ----- end compiler output: DMD win 1.029 ----- |
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:g4ejen$10a$1@digitalmars.com... > Just for the hell of it, I tried changing all three "alias Foo_dwc(T) Foo;" to "alias Foo_dwc!(T) Foo;" (ie, added "!"): > > ----- start test2.d ----- > public template Foo(T: char) {alias Foo_dwc!(T) Foo; } > public template Foo(T: wchar) {alias Foo_dwc!(T) Foo; } > public template Foo(T: dchar) {alias Foo_dwc!(T) Foo; } > > private void Foo_dwc(T)(T arg) { } > > void main(char[][] args) > { > Foo('a'); > } Right, the bangs are necessary. > ----- end test2.d ----- > ----- start compiler output: DMD win 1.029 ----- > test2.d(1): template test2.Foo(T : char) is not a function template > test2.d(9): template test2.Foo(T : char) cannot deduce template function > from argument types (char) > ----- end compiler output: DMD win 1.029 ----- And this is the sad outcome -- once you do this, Foo is no longer a function template, and so it can't have IFTI performed on it. *sigh* |
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:g4es21$l49$1@digitalmars.com... > "Nick Sabalausky" <a@a.a> wrote in message news:g4ejen$10a$1@digitalmars.com... > >> Just for the hell of it, I tried changing all three "alias Foo_dwc(T) Foo;" to "alias Foo_dwc!(T) Foo;" (ie, added "!"): >> >> ----- start test2.d ----- >> public template Foo(T: char) {alias Foo_dwc!(T) Foo; } >> public template Foo(T: wchar) {alias Foo_dwc!(T) Foo; } >> public template Foo(T: dchar) {alias Foo_dwc!(T) Foo; } >> >> private void Foo_dwc(T)(T arg) { } >> >> void main(char[][] args) >> { >> Foo('a'); >> } > > Right, the bangs are necessary. > >> ----- end test2.d ----- >> ----- start compiler output: DMD win 1.029 ----- >> test2.d(1): template test2.Foo(T : char) is not a function template >> test2.d(9): template test2.Foo(T : char) cannot deduce template function >> from argument types (char) >> ----- end compiler output: DMD win 1.029 ----- > > And this is the sad outcome -- once you do this, Foo is no longer a function template, and so it can't have IFTI performed on it. *sigh* > I'm still somewhat new to D's templates (been spending a lot of time in non-D development...not by choice), so I'm trying to understand exactly what's going on here as best as I can. Looked up "IFTI" (Implicit Function Template Instantiation), so I see now this method (test2.d) does work, but you have to explicitly instantiate the Foo template when calling the function: In main: "Foo('a');" -> "Foo!(char)('a');" That works. The first compiler error being from line 1 threw me off, didn't realize that was just a result of the line 9 error below. But could you explain how it is that Foo stops being a function template? Or rather, what is the compiler doing when attempting to process line 9 in both the broken "Foo('a');" and fixed "Foo!(char)('a');" scenarios? |
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:g4f8aa$1bkq$1@digitalmars.com... > > I'm still somewhat new to D's templates (been spending a lot of time in non-D development...not by choice), so I'm trying to understand exactly what's going on here as best as I can. Looked up "IFTI" (Implicit Function Template Instantiation), so I see now this method (test2.d) does work, but you have to explicitly instantiate the Foo template when calling the function: > > In main: > "Foo('a');" -> "Foo!(char)('a');" > > That works. The first compiler error being from line 1 threw me off, didn't realize that was just a result of the line 9 error below. > > But could you explain how it is that Foo stops being a function template? Or rather, what is the compiler doing when attempting to process line 9 in both the broken "Foo('a');" and fixed "Foo!(char)('a');" scenarios? From what I understand, the compiler considers a template to be a template function if an only if it has exactly one member named the same thing as itself, and that member is a function declaration. Aliases are not function declarations so it fails, though one could argue that an alias is simply a reference _to_ another symbol, so this should work. Of course, none of this is specified. It can't deduce the template function on line 9 simply because it doesn't think that Foo is a template function. |
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | "Jarrett Billingsley" wrote
> "Nick Sabalausky" wrote
>>
>> I'm still somewhat new to D's templates (been spending a lot of time in non-D development...not by choice), so I'm trying to understand exactly what's going on here as best as I can. Looked up "IFTI" (Implicit Function Template Instantiation), so I see now this method (test2.d) does work, but you have to explicitly instantiate the Foo template when calling the function:
>>
>> In main:
>> "Foo('a');" -> "Foo!(char)('a');"
>>
>> That works. The first compiler error being from line 1 threw me off, didn't realize that was just a result of the line 9 error below.
>>
>> But could you explain how it is that Foo stops being a function template? Or rather, what is the compiler doing when attempting to process line 9 in both the broken "Foo('a');" and fixed "Foo!(char)('a');" scenarios?
>
> From what I understand, the compiler considers a template to be a template function if an only if it has exactly one member named the same thing as itself, and that member is a function declaration. Aliases are not function declarations so it fails, though one could argue that an alias is simply a reference _to_ another symbol, so this should work. Of course, none of this is specified.
>
> It can't deduce the template function on line 9 simply because it doesn't think that Foo is a template function.
In that case, this should work, but generates extra code (which should be inlined):
public void Foo(T: char)(T arg) {Foo_dwc!(T)(arg); }
public void Foo(T: wchar)(T arg) {Foo_dwc!(T)(arg); }
public void Foo(T: dchar)(T arg) {Foo_dwc!(T)(arg); }
private void Foo_dwc(T)(T arg) { }
void main(char[][] args)
{
Foo('a');
}
(not tested)
-Steve
|
July 02, 2008 Re: Multiple Template Specialization Types (in D1)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:g4g2fg$a4l$1@digitalmars.com... > > In that case, this should work, but generates extra code (which should be inlined): > > public void Foo(T: char)(T arg) {Foo_dwc!(T)(arg); } > public void Foo(T: wchar)(T arg) {Foo_dwc!(T)(arg); } > public void Foo(T: dchar)(T arg) {Foo_dwc!(T)(arg); } > > private void Foo_dwc(T)(T arg) { } > > void main(char[][] args) > { > Foo('a'); > } It does. :) |
Copyright © 1999-2021 by the D Language Foundation