Thread overview
Template alias parameters break specialisation
Jul 15, 2004
Cabal
Jul 15, 2004
Andrew Edwards
Jul 15, 2004
Andrew Edwards
Jul 16, 2004
Cabal
Jul 16, 2004
Andrew
Jul 16, 2004
Cabal
Jul 16, 2004
Stewart Gordon
July 15, 2004
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



July 15, 2004
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
July 15, 2004
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.
July 16, 2004
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.

July 16, 2004
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.
>


July 16, 2004
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.
>>

July 16, 2004
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.
<snip>

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.