Specialization - Major hole in the spec?

Sean Kelly sean at invisibleduck.org
Wed Jan 4 16:50:20 PST 2012


On Jan 4, 2012, at 4:47 PM, Peter Alexander wrote:

> I've had a look through the spec, as well as TDPL. Andrei's book mentions nothing about template specialization, and the website is scarce on the details. In particular, nothing is mentioned about the interplay between specialization and overloading -- something that is very often misunderstood in C++.
> 
> I have three questions:
> 
> -----------------------------------------------------------------------
> 
> Question 1: Is a function specialization's signature required to match the primary template signature like in C++? e.g.
> 
> void foo(T)(T t);           // 1
> void foo(T : float)(int t); // 2
> 
> Is this legal? DMD allows it. If so, what should these calls do?

I'd say it's illegal, and so all overloading results related to calling these routines should be ignored.


> -----------------------------------------------------------------------
> 
> Question 2: How do specializations and overloads play together?
> 
> Example:
> 
> void foo(T)(T t);  // 1
> void foo(T)(T* t); // 2
> void foo(int* t);  // 3
> 
> foo(new int); // what does this call?

3


> void foo(T)(T t);  // 1
> void foo(int* t);  // 3
> void foo(T)(T* t); // 2
> 
> foo(new int); // what does this call now that 2 & 3 are swapped?

3.  I don't think declaration order should be significant as it is in C++.


> People that know their C++ will recognize this as the Dimov/Abrahams example. The equivalent code in C++ calls 3 in the first case and 2 in the second because of the way overloads and specializations work. Yes, it depends on the order you write the functions. See http://www.gotw.ca/publications/mill17.htm for more details.
> 
> DMD currently gives an error saying that function 3 conflicts with function 1. Is this correct? Why?

Because function 3 is not a template, and D doesn't currently allow templates to be overloaded with non-templates (though I know that's a goal).  For now:

void foo()(int* t); // 3


> -----------------------------------------------------------------------
> 
> Question 3: When specializing, am I required to keep using T instead of what it is specialized to?
> 
> A couple of illustrating examples:
> 
> void foo(T)(T t);       // 1
> void foo(T : int)(T t); // 2
> 
> foo(0); // DMD calls 2 as expected
> 
> 
> void bar(T)(T t);         // 1
> void bar(T : int)(int t); // 2
> 
> bar(0); // DMD calls 1 (!)
> 
> What are the rules here? Is DMD correct? I find this behavior very surprising.

Looks like another bug.


More information about the Digitalmars-d mailing list