Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
January 21, 2016 Template specialization | ||||
---|---|---|---|---|
| ||||
How do you create a template that accepts many types. But overrides just one of them? Don't want to write out all of the specializations. Hours of google and I'm sure it's simple... -=Darrell |
January 21, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On Thu, Jan 21, 2016 at 11:37:34PM +0000, Darrell Gallion via Digitalmars-d-learn wrote: > How do you create a template that accepts many types. > But overrides just one of them? > Don't want to write out all of the specializations. > > Hours of google and I'm sure it's simple... [...] I'm afraid your question is a little too ambiguous. Could you rephrase what it is you're trying to accomplish? Maybe with some code snippet that you want to work but currently doesn't? I'm not sure I understand why you have to write out any of the specializations at all... or what you mean by "override". T -- It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe? |
January 21, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On 01/21/2016 03:37 PM, Darrell Gallion wrote:
> How do you create a template that accepts many types.
> But overrides just one of them?
> Don't want to write out all of the specializations.
>
> Hours of google and I'm sure it's simple...
>
> -=Darrell
The straightforward approach is tricky because the ': int' syntax means "is implicitly convertible"; so, even the case where B is 'char' would be bound to the specialization:
void foo(A, B, C)() {
pragma(msg, "general");
}
void foo(A, B : int, C)() { // <-- 'B : int' specialization
pragma(msg, "special");
}
void main() {
foo!(char, string, double)();
foo!(short, int, float)();
}
A better approach is using template constraints:
void foo(A, B, C)()
if (!is (B == int)) { // <-- 'B != int'
pragma(msg, "general");
}
void foo(A, B, C)()
if (is (B == int)) { // <-- 'B == int'
pragma(msg, "special");
}
void main() {
foo!(char, string, double)();
foo!(short, int, float)();
}
But that has its own problem of needing to reverse the logic for the general case (and other cases), which may become very complicated to write (or to get right) in some cases.
Ali
|
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 22 January 2016 at 00:08:56 UTC, Ali Çehreli wrote:
> On 01/21/2016 03:37 PM, Darrell Gallion wrote:
>> How do you create a template that accepts many types.
>> But overrides just one of them?
>> Don't want to write out all of the specializations.
>>
>> Hours of google and I'm sure it's simple...
>>
>> -=Darrell
>
> The straightforward approach is tricky because the ': int' syntax means "is implicitly convertible"; so, even the case where B is 'char' would be bound to the specialization:
>
> void foo(A, B, C)() {
> pragma(msg, "general");
> }
>
> void foo(A, B : int, C)() { // <-- 'B : int' specialization
> pragma(msg, "special");
> }
>
> void main() {
> foo!(char, string, double)();
> foo!(short, int, float)();
> }
>
> A better approach is using template constraints:
>
> void foo(A, B, C)()
> if (!is (B == int)) { // <-- 'B != int'
> pragma(msg, "general");
> }
>
> void foo(A, B, C)()
> if (is (B == int)) { // <-- 'B == int'
> pragma(msg, "special");
> }
>
> void main() {
> foo!(char, string, double)();
> foo!(short, int, float)();
> }
>
> But that has its own problem of needing to reverse the logic for the general case (and other cases), which may become very complicated to write (or to get right) in some cases.
>
> Ali
I must apologize for such a vague question. Frustration had me.
import std.stdio;
void foo(A)()
if (!is (A == int)) {
pragma(msg, "int");
}
void foo(A)()
if (is (A == int[])) {
pragma(msg, "int[]");
}
void main() {
foo!(int)();
foo!(int[])();
}
===========
source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are:
source\app.d(3): app.foo(A)() if (!is(A == int))
source\app.d(8): app.foo(A)() if (is(A == int[]))
source\app.d(16): Error: app.foo called with argument types () matches both:
source\app.d(3): app.foo!(int[]).foo()
and:
source\app.d(8): app.foo!(int[]).foo()
|
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:
> void foo(A)()
> if (!is (A == int)) {
> pragma(msg, "int");
> }
>
> void foo(A)()
> if (is (A == int[])) {
> pragma(msg, "int[]");
> }
>
> void main() {
>
> foo!(int)();
> foo!(int[])();
> }
>
> ===========
>
> source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are:
> source\app.d(3): app.foo(A)() if (!is(A == int))
> source\app.d(8): app.foo(A)() if (is(A == int[]))
> source\app.d(16): Error: app.foo called with argument types () matches both:
> source\app.d(3): app.foo!(int[]).foo()
> and:
> source\app.d(8): app.foo!(int[]).foo()
Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
|
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote:
> On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:
>> void foo(A)()
>> if (!is (A == int)) {
>> pragma(msg, "int");
>> }
>>
>> void foo(A)()
>> if (is (A == int[])) {
>> pragma(msg, "int[]");
>> }
>>
>> void main() {
>>
>> foo!(int)();
>> foo!(int[])();
>> }
>>
>> ===========
>>
>> source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are:
>> source\app.d(3): app.foo(A)() if (!is(A == int))
>> source\app.d(8): app.foo(A)() if (is(A == int[]))
>> source\app.d(16): Error: app.foo called with argument types () matches both:
>> source\app.d(3): app.foo!(int[]).foo()
>> and:
>> source\app.d(8): app.foo!(int[]).foo()
>
> Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
I'm aware this doesn't look right or compile.
How do I do this?
void foo(int x)
{ }
void foo(int [] x)
{ }
template foo(T)(T x){}
void main() {
int x;
int [] a;
foo((x);
foo(a);
foo("hi");
}
|
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On Friday, 22 January 2016 at 13:03:52 UTC, Darrell Gallion wrote:
> On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote:
>> On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:
>>> void foo(A)()
>>> if (!is (A == int)) {
>>> pragma(msg, "int");
>>> }
>>>
>>> void foo(A)()
>>> if (is (A == int[])) {
>>> pragma(msg, "int[]");
>>> }
>>>
>>> void main() {
>>>
>>> foo!(int)();
>>> foo!(int[])();
>>> }
>>>
>>> ===========
>>>
>>> source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are:
>>> source\app.d(3): app.foo(A)() if (!is(A == int))
>>> source\app.d(8): app.foo(A)() if (is(A == int[]))
>>> source\app.d(16): Error: app.foo called with argument types () matches both:
>>> source\app.d(3): app.foo!(int[]).foo()
>>> and:
>>> source\app.d(8): app.foo!(int[]).foo()
>>
>> Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
>
> I'm aware this doesn't look right or compile.
> How do I do this?
>
>
> void foo(int x)
> { }
>
> void foo(int [] x)
> { }
>
> template foo(T)(T x){}
>
> void main() {
> int x;
> int [] a;
> foo((x);
> foo(a);
> foo("hi");
> }
What was getting me...
Defining the templates within another function, fails.
void main(){
long foo(T: int)(T t)
{
return cast(long)t;
}
long[] foo(T: int[])(T t)
{ long [] ar;
return ar;
}
T foo(T)(T t)
{ return t; }
foo(1);
foo([1,2]);
foo("hi");
}
source/app.d(224,3): Error: declaration foo(T : int[])(T t) is already defined
source/app.d(229,3): Error: declaration foo(T)(T t) is already defined
source/app.d(236,6): Error: template D main.foo cannot deduce function from argument types !()(int[]), candidates are:
source/app.d(219,8): app.main.foo(T : int)(T t)
source/app.d(237,6): Error: template D main.foo cannot deduce function from argument types !()(string), candidates are:
source/app.d(219,8): app.main.foo(T : int)(T t)
|
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On Friday, 22 January 2016 at 13:03:52 UTC, Darrell Gallion wrote: > On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote: >> On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote: >>> void foo(A)() >>> if (!is (A == int)) { >>> pragma(msg, "int"); >>> } >>> >>> void foo(A)() >>> if (is (A == int[])) { >>> pragma(msg, "int[]"); >>> } >>> >>> void main() { >>> >>> foo!(int)(); >>> foo!(int[])(); >>> } >>> >>> =========== >>> >>> source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: >>> source\app.d(3): app.foo(A)() if (!is(A == int)) >>> source\app.d(8): app.foo(A)() if (is(A == int[])) >>> source\app.d(16): Error: app.foo called with argument types () matches both: >>> source\app.d(3): app.foo!(int[]).foo() >>> and: >>> source\app.d(8): app.foo!(int[]).foo() >> >> Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous. > > I'm aware this doesn't look right or compile. > How do I do this? > Just remove the `!` in the first template constraint, and it will compile. > > void foo(int x) > { } > > void foo(int [] x) > { } > > template foo(T)(T x){} > > void main() { > int x; > int [] a; > foo((x); > foo(a); > foo("hi"); > } You lost me here... |
January 22, 2016 Re: Template specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Darrell Gallion | On 01/22/2016 07:41 AM, Darrell Gallion wrote: > Defining the template [specializations] within another function, fails. Reported: https://issues.dlang.org/show_bug.cgi?id=15592 Ali |
Copyright © 1999-2021 by the D Language Foundation