Can a D library have some types determined by the client program?

Liam McGillivray yoshi.pit.link.mario at gmail.com
Fri Mar 8 06:03:51 UTC 2024


On Friday, 8 March 2024 at 03:19:59 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
>
> On 08/03/2024 4:09 PM, Liam McGillivray wrote:
>> 
>> Thank you. Is this first example you gave the template? Is the 
>> syntax `(ATile : Tile)` saying that ATile must be a derived 
>> class of Tile? If this isn't worse in any way than your second 
>> example, then I don't know why I wouldn't choose this one.
>
> Typically in D we use templates quite heavily, but what you are 
> wanting is probably more familiar to you via the OOP method 
> with a factory of some kind.
Nope, but thank you. I am not a very experienced programmer. The 
most complex thing I've ever done previous to this was my work on 
[Condorcet](https://github.com/julien-boudry/Condorcet) which is 
in PHP. I might have encountered something about factory methods, 
but I don't remember. I have some C++ experience, but I haven't 
been very successful with it. What I have so far in the game I'm 
making is the most complex program I have ever written.

>> I suppose that if I do this, then the derived class `Mission` 
>> would be declared like `class Mission : Map(GridTile)`, right?
>
> ``class Mission : Map!GridTile`` but right idea.
>
>> When I tried adding that parameter to the Map class, on 
>> attempting to build it it complained that references to Map in 
>> other classes were incomplete, as they didn't include a 
>> parameter. I suppose I must make my other classes templates 
>> too.
I have an update on this, after taking another go at it.

A problem I have is that the 3 classes Map, Tile, and Unit 
reference each-other. If I turn Map into a template, than it 
complains about the member variable of Unit declared as `Map 
map;` without arguments. I change this line to `Map!TileType 
map;` but this requires that Unit is also turned into a template. 
After changing `class Unit` to `class Unit (TileType), it 
complains about the line `Unit* occupant;` in Tile. I try turning 
Tile into a template with the `TileType` parameter, which means 
that the class inheriting Tile will need to use itself as a 
parameter. Surprisingly, I have done this and it hasn't taken 
issue (so far). But now that I have turned Tile into a template, 
it complains about the declaration of Map being `class Map 
(TileType : Tile)`, as `Tile` is no longer a class but a template.

Here are some of the build errors:
```
     Starting Performing "debug" build using /usr/bin/dmd for 
x86_64.
   Up-to-date bindbc-freetype 1.1.1: target for configuration 
[staticBC] is up to date.
   Up-to-date fluid 0.6.3: target for configuration [default] is 
up to date.
     Building open_emblem_raylib ~master: building configuration 
[application]
../source/map.d(185,13): Error: template class 
`unit.Unit(TileType)` is used as a type without instantiation; to 
instantiate it use `Unit!(arguments)`
../source/map.d(21,19): Error: template class 
`unit.Unit(TileType)` is used as a type without instantiation; to 
instantiate it use `Unit!(arguments)`
../source/map.d(22,27): Error: template class 
`unit.Unit(TileType)` is used as a type without instantiation; to 
instantiate it use `Unit!(arguments)`
../source/map.d(125,11): Error: template class 
`tile.Tile(TileType)` is used as a type without instantiation; to 
instantiate it use `Tile!(arguments)`
../source/map.d(129,14): Error: template class 
`tile.Tile(TileType)` is used as a type without instantiation; to 
instantiate it use `Tile!(arguments)`
../source/map.d(133,11): Error: template class 
`unit.Unit(TileType)` is used as a type without instantiation; to 
instantiate it use `Unit!(arguments)`
../source/unit.d(12,12): Error: template instance 
`map.Map!(VisibleTile)` error instantiating
../source/tile.d(19,9):        instantiated from here: 
`Unit!(VisibleTile)`
source/vtile.d(4,21):        instantiated from here: 
`Tile!(VisibleTile)`
```

Will I somehow manage to solve this problem?

Given that it's possible to declare an object inside a class, and 
then fill it with an object of a derived class, I would have 
thought it would be possible to use a template as a type, and 
then fill it with an object of a class derived from that template.


More information about the Digitalmars-d-learn mailing list