www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Template alias parameters break specialisation

reply Cabal <cabalN05P4M myrealbox.com> writes:
The following code does not compile and gives the error at the bottom.
Removal of the alias template parameter specifications allows it to
compile.

,----[  ]
| 
| template SpecTest(alias T, int n) {
|   alias T X;
| }
| 
| template SpecTest(alias T, int n :0) {
|   alias T X;
| }
| 
| class Dummy {}
| 
| void main() {
|   alias SpecTest!(Dummy, 0).X Y;
| }
| 
`----

template instance SpecTest!(Dummy ,0) matches more than one template
declaration
Jul 15 2004
parent reply Andrew Edwards <ridimz_at yahoo.dot.com> writes:
Cabal wrote:
 The following code does not compile and gives the error at the bottom.
 Removal of the alias template parameter specifications allows it to
 compile.
 
 ,----[  ]
 | 
 | template SpecTest(alias T, int n) {
 |   alias T X;
 | }
 | 
 | template SpecTest(alias T, int n :0) {
 |   alias T X;
 | }

An int is automatically initialized to zero, so there is nothing special about inheriting from zero. Both templates are _still_ the same.
 | class Dummy {}
 | 
 | void main() {
 |   alias SpecTest!(Dummy, 0).X Y;
 | }
 | 
 `----
 
 template instance SpecTest!(Dummy ,0) matches more than one template
 declaration
 
 
 

And the compiler is correct. Zero is an int so the first template applies, it also matches the second template: an int inherited from zero. I don't understand why you would need to do something like this. Please explain! Andrew
Jul 15 2004
parent reply Andrew Edwards <ridimz_at yahoo.dot.com> writes:
Andrew Edwards wrote:
 Cabal wrote:
 
 The following code does not compile and gives the error at the bottom.
 Removal of the alias template parameter specifications allows it to
 compile.

 ,----[  ]
 | | template SpecTest(alias T, int n) {
 |   alias T X;
 | }
 | | template SpecTest(alias T, int n :0) {
 |   alias T X;
 | }

An int is automatically initialized to zero, so there is nothing special about inheriting from zero. Both templates are _still_ the same.
 | class Dummy {}
 | | void main() {
 |   alias SpecTest!(Dummy, 0).X Y;
 | }
 | `----

 template instance SpecTest!(Dummy ,0) matches more than one template
 declaration

And the compiler is correct. Zero is an int so the first template applies, it also matches the second template: an int inherited from zero. I don't understand why you would need to do something like this. Please explain! Andrew

By the way, your example works with any other number than zero. So: alias SpecTest!(Dummy, 1).X Y; works or if you change the template SpecTest to: Template SpecTest(alias T, int n:1) and leave the rest of your example alone, it works fine.
Jul 15 2004
parent reply Cabal <cabalN05P4M myrealbox.com> writes:
Andrew - as the subject suggests, that is a specialisation *not* an
initialiser. 
':' specialisation
'=' default initialiser

They are different concepts. Read the spec, it gives a reasonably simple
example of use for specialisation (calculating a factorial I think)

Andrew Edwards wrote:

 Andrew Edwards wrote:
 Cabal wrote:
 
 The following code does not compile and gives the error at the bottom.
 Removal of the alias template parameter specifications allows it to
 compile.

 ,----[  ]
 | | template SpecTest(alias T, int n) {
 |   alias T X;
 | }
 | | template SpecTest(alias T, int n :0) {
 |   alias T X;
 | }

An int is automatically initialized to zero, so there is nothing special about inheriting from zero. Both templates are _still_ the same.
 | class Dummy {}
 | | void main() {
 |   alias SpecTest!(Dummy, 0).X Y;
 | }
 | `----

 template instance SpecTest!(Dummy ,0) matches more than one template
 declaration

And the compiler is correct. Zero is an int so the first template applies, it also matches the second template: an int inherited from zero. I don't understand why you would need to do something like this. Please explain! Andrew

By the way, your example works with any other number than zero. So: alias SpecTest!(Dummy, 1).X Y; works or if you change the template SpecTest to: Template SpecTest(alias T, int n:1) and leave the rest of your example alone, it works fine.

Jul 16 2004
parent reply Andrew <Andrew_member pathlink.com> writes:
In article <cd83m6$31fl$2 digitaldaemon.com>, Cabal says...
Andrew - as the subject suggests, that is a specialisation *not* an
initialiser. 
':' specialisation
'=' default initialiser

They are different concepts. Read the spec, it gives a reasonably simple
example of use for specialisation (calculating a factorial I think)

Your grasp of the English language is quite impressive. Please remind me not to speak before I pick up my oxford learners dictionary and bash me over the head with it! Unfortunately your gift has blinded your ability to effectively identify an error even if it slaps you in the face. You have two templates: one that's "specialized" to accept only zero as a second argument and another that accepts any integer (_including zero_). Then you tell the computer to create an instance of the template that accepts zero as its second parameter. How is the compiler to tell which template you mean when they _both_ accept zero? Your request is ambiguous. It doesn't require a degree in proper English usage to figure that out.
Andrew Edwards wrote:

 Andrew Edwards wrote:
 Cabal wrote:
 
 The following code does not compile and gives the error at the bottom.
 Removal of the alias template parameter specifications allows it to
 compile.

 ,----[  ]
 | | template SpecTest(alias T, int n) {
 |   alias T X;
 | }
 | | template SpecTest(alias T, int n :0) {
 |   alias T X;
 | }

An int is automatically initialized to zero, so there is nothing special about inheriting from zero. Both templates are _still_ the same.
 | class Dummy {}
 | | void main() {
 |   alias SpecTest!(Dummy, 0).X Y;
 | }
 | `----

 template instance SpecTest!(Dummy ,0) matches more than one template
 declaration

And the compiler is correct. Zero is an int so the first template applies, it also matches the second template: an int inherited from zero. I don't understand why you would need to do something like this. Please explain! Andrew

By the way, your example works with any other number than zero. So: alias SpecTest!(Dummy, 1).X Y; works or if you change the template SpecTest to: Template SpecTest(alias T, int n:1) and leave the rest of your example alone, it works fine.


Jul 16 2004
next sibling parent Cabal <cabalN05P4M myrealbox.com> writes:
Andrew wrote:

 In article <cd83m6$31fl$2 digitaldaemon.com>, Cabal says...
Andrew - as the subject suggests, that is a specialisation *not* an
initialiser.
':' specialisation
'=' default initialiser

They are different concepts. Read the spec, it gives a reasonably simple
example of use for specialisation (calculating a factorial I think)

Your grasp of the English language is quite impressive. Please remind me not to speak before I pick up my oxford learners dictionary and bash me over the head with it! Unfortunately your gift has blinded your ability to effectively identify an error even if it slaps you in the face.

Partial apologies Andrew. I read your statement "An int is automatically initialized to zero, so there is nothing special about inheriting from zero." as "... initialising from zero" - my mind obviously short circuited the attempt to understand how you 'inherit' from 0 and substituted 'initialise' as at least that would have had some logical context to fit into even if it was based on an mistaken assumption on your part. Now read on.
 
 You have two templates: one that's "specialized" to accept only zero as a
 second argument and another that accepts any integer (_including zero_).
 Then you tell the computer to create an instance of the template that
 accepts zero as its second parameter.
 
 How is the compiler to tell which template you mean when they _both_
 accept zero? Your request is ambiguous. It doesn't require a degree in
 proper English usage to figure that out.
 

Thats the whole point of specialisation: it directs the compiler to ignore the general case and choose the 'specialised' case if it is a closer match. My condolences if you feel you are being beaten around the head with the Oxford learners dictionary (you'll find 'condolences' under C btw). I had rather intended that you felt you were being beaten with the D spec where you will find 'speciali[s|z]ation defined under Templates). Tinfoil hats on! Is everyone on these NG's a touchy bugger? Or do I have some special talent for attracting them :)
Andrew Edwards wrote:

 Andrew Edwards wrote:
 Cabal wrote:
 
 The following code does not compile and gives the error at the bottom.
 Removal of the alias template parameter specifications allows it to
 compile.

 ,----[  ]
 | | template SpecTest(alias T, int n) {
 |   alias T X;
 | }
 | | template SpecTest(alias T, int n :0) {
 |   alias T X;
 | }

An int is automatically initialized to zero, so there is nothing special about inheriting from zero. Both templates are _still_ the same.
 | class Dummy {}
 | | void main() {
 |   alias SpecTest!(Dummy, 0).X Y;
 | }
 | `----

 template instance SpecTest!(Dummy ,0) matches more than one template
 declaration

And the compiler is correct. Zero is an int so the first template applies, it also matches the second template: an int inherited from zero. I don't understand why you would need to do something like this. Please explain! Andrew

By the way, your example works with any other number than zero. So: alias SpecTest!(Dummy, 1).X Y; works or if you change the template SpecTest to: Template SpecTest(alias T, int n:1) and leave the rest of your example alone, it works fine.



Jul 16 2004
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrew wrote:

<snip>
 How is the compiler to tell which template you mean when they _both_ accept
 zero? Your request is ambiguous. It doesn't require a degree in proper English
 usage to figure that out.

From the spec: "The template picked to instantiate is the one that is most specialized that fits the types of the TemplateArgumentList. Determine which is more specialized is done the same way as the C++ partial ordering rules. If the result is ambiguous, it is an error." There's nothing ambiguous about whether int n or int n:0 is more specific. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Jul 16 2004