Jump to page: 1 2
Thread overview
Multiple Template Specialization Types (in D1)?
Jul 01, 2008
Nick Sabalausky
Jul 01, 2008
Nick Sabalausky
Jul 01, 2008
BCS
Jul 02, 2008
Nick Sabalausky
Jul 02, 2008
Nick Sabalausky
Jul 02, 2008
Nick Sabalausky
Jul 02, 2008
Nick Sabalausky
Jul 02, 2008
BCS
Jul 02, 2008
BCS
July 01, 2008
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
"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
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
"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
"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
"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
"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
"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
"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
"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.  :)


« First   ‹ Prev
1 2