www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - : in template specialization vs constraint

reply Shriramana Sharma <samjnaa_dont_spam_me gmail.com> writes:
import std.stdio;
void func(T)(T v) { writeln(1); }
void func(T: int)(T v) { writeln(2); }
void func(T)(T v) if (is(T: int)) { writeln(3); }
void main()
{
    func(100);
    ubyte s = 200;
    func(s);
}

The above code prints 2 twice. A fwe questions:

1) At func(100) why isn't the compiler complaining that it is able to match 
two templates i.e. the ones printing 2 and 3? Is it that since the second 
one is specialized but the third one apparently isn't, the compiler just 
ignores the third one?

2) How come func(s) doesn't invoke the template that prints 3? `T: int` in 
the context of specialization means an exact match but in the context of 
constraints it means implicitly convertible, no? The specialization section 
under http://dlang.org/spec/template.html is not very clear about this IMHO.

-- 
Shriramana Sharma, Penguin #395953
Dec 22 2015
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 22 December 2015 at 15:29:16 UTC, Shriramana Sharma 
wrote:
 1) At func(100) why isn't the compiler complaining that it is 
 able to match two templates i.e. the ones printing 2 and 3?
Because the specialized one just wins the context. It only complains when there's two equal ones. Constraints serve only to add or remove the template from the consideration list. If the constraint fails, the compiler considers that template to not even exist. If it passes, it adds the template to the overload list and then proceeds like it normally would without looking at the constraint again. Since your constraint passed, #3 is added to the list along side #1 and #2. Then, since #2 is specialized, it gets picked instead of the others.
 2) How come func(s) doesn't invoke the template that prints 3? 
 `T: int` in the context of specialization means an exact match 
 but in the context of constraints it means implicitly 
 convertible, no? The specialization section under 
 http://dlang.org/spec/template.html is not very clear about 
 this IMHO.
In specialization, it will implicitly convert, it will just select the best match available. Make #1: void func(T : ubyte)(T v) { writeln(1); } It will then use that for for the second line because it is a *better* match than :int, but :int still is a match so it works as a fallback.
Dec 22 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/22/15 10:40 AM, Adam D. Ruppe wrote:

 In specialization, it will implicitly convert, it will just select the
 best match available.

 Make #1:

      void func(T : ubyte)(T v) { writeln(1); }

 It will then use that for for the second line because it is a *better*
 match than :int, but :int still is a match so it works as a fallback.
Type specialization has some weird properties in this regard. Sometimes it needs to be exact or explicit, sometimes it doesn't. http://forum.dlang.org/post/rvflnpxwzetpcphwxrgx forum.dlang.org -Steve
Dec 22 2015