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.