digitalmars.D - Template specialization ordering rules
- David Nadlinger (17/17) Apr 10 2011 Consider this template declaration: struct Foo(T : Bar!R, U = int, R) {}
- Jonathan M Davis (34/55) Apr 10 2011 the
- David Nadlinger (11/13) Apr 10 2011 No, that isn't the issue here – there are specialization rules in plac...
- Walter Bright (2/18) Apr 10 2011 It's a bug, it should select the second one. Please post to bugzilla.
- David Nadlinger (3/4) Apr 10 2011 Done: http://d.puremagic.com/issues/show_bug.cgi?id=5830.
Consider this template declaration: struct Foo(T : Bar!R, U = int, R) {} As intended, it matches Foo!(Bar!float), with Bar being some other parametrized type and R being correctly inferred as float. However, it doesn't seem to count as more specialized than just »struct Foo(T)« – for example, the following snippet produces an ambiguity error with the latest DMD 2 (0219a5f): --- struct Foo(T) {} struct Foo(T : Bar!R, U = int, R) {} struct Bar(R) {} Foo!(Bar!float) f; --- Is this a bug or by design? http://digitalmars.com/d/2.0/template.html unfortunately just says »Determine which is more specialized is done the same way as the C++ partial ordering rules.«, which isn't really helpful if you don't have a copy of the C++ spec at hand… David
Apr 10 2011
Consider this template declaration: struct Foo(T : Bar!R, U =3D int, R) {} =20 As intended, it matches Foo!(Bar!float), with Bar being some other parametrized type and R being correctly inferred as float. =20 However, it doesn't seem to count as more specialized than just =C2=BBstr=uctFoo(T)=C2=AB =E2=80=93 for example, the following snippet produces an amb=iguity errorwith the latest DMD 2 (0219a5f): =20 --- struct Foo(T) {} struct Foo(T : Bar!R, U =3D int, R) {} struct Bar(R) {} =20 Foo!(Bar!float) f; --- =20 Is this a bug or by design? http://digitalmars.com/d/2.0/template.html unfortunately just says =C2=BBDetermine which is more specialized is done=thesame way as the C++ partial ordering rules.=C2=AB, which isn't really hel=pfulif you don't have a copy of the C++ spec at hand=E2=80=A6C++ templates don't have the concept of : in them. Template specializes in = C++=20 are only on exact type, not implicit conversion or inheritance. So, if C++= =20 disambiguation rules are used exactly, then : would have to be ignored. I think that the issue here is that Foo!(bar!float) works with _both_=20 templates. I don't remember what the exact rules are, but in my experience,= D=20 never chooses based on precedence. Things match exactly or there's an=20 ambiguity. That being the case, you would have to make the first Foo so tha= t=20 it doesn't match _anything_ which matches the second one. To do that, you'd= =20 probably have to use a template constraint - something similar to if(!is(T : Bar!R)) but you can't use quite that constraint because the first Foo has no R. So,= it=20 could be difficult to make it so that they don't match. You could play around with more basic templates such as struct Foo(T) {} struct Foo(T : int) {} and see whether they have the same problem. If they don't, then maybe you'v= e=20 actually found a bug. I don't know. Templates get to be a bit complicated w= hen=20 you have specializations. The general rule of thumb - if not absolute rule = =2D=20 is that they need to be written in such a way that they don't conflict at a= ll. =2D Jonathan M Davis
Apr 10 2011
On 4/10/11 10:15 PM, Jonathan M Davis wrote:I think that the issue here is that Foo!(bar!float) works with _both_ templates.[snip tldr]No, that isn't the issue here – there are specialization rules in place for D templates as well. Actually, I should have mentioned that the sample works fine without the U parameter on the specialization: --- struct Foo(T) {} struct Foo(T : Bar!R, R) {} struct Bar(R) {} Foo!(Bar!float) f; // correctly instantiates the second one --- David
Apr 10 2011
On 4/10/2011 12:32 PM, David Nadlinger wrote:Consider this template declaration: struct Foo(T : Bar!R, U = int, R) {} As intended, it matches Foo!(Bar!float), with Bar being some other parametrized type and R being correctly inferred as float. However, it doesn't seem to count as more specialized than just »struct Foo(T)« – for example, the following snippet produces an ambiguity error with the latest DMD 2 (0219a5f): --- struct Foo(T) {} struct Foo(T : Bar!R, U = int, R) {} struct Bar(R) {} Foo!(Bar!float) f; --- Is this a bug or by design? http://digitalmars.com/d/2.0/template.html unfortunately just says »Determine which is more specialized is done the same way as the C++ partial ordering rules.«, which isn't really helpful if you don't have a copy of the C++ spec at hand…It's a bug, it should select the second one. Please post to bugzilla.
Apr 10 2011
On 4/10/11 11:14 PM, Walter Bright wrote:It's a bug, it should select the second one. Please post to bugzilla.Done: http://d.puremagic.com/issues/show_bug.cgi?id=5830. David
Apr 10 2011