www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template struct question

reply WhatMeWorry <kheaser gmail.com> writes:
```
void main()
{

struct HexBoard(F,I)
{
     this(F d, I r, I c) {}
     //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles 
fine!
}

void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined 
identifier F and I


auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

}


Is there any clever way to move the method outside of a templated 
block structure?  Or is this as good as it gets.

I tried
// Explicit instantiation for 'int' type
//int add!(int, int);
void displayHexBoardData(HexBoard2!(float,uint) h);  // 
declaration

but that just returns
Error: declaration `displayHexBoard` is already defined
onlineapp.d(10):        `function` `displayHexBoard` is defined 
here
Feb 12
next sibling parent =?UTF-8?Q?Ali_=C3=87ehreli?= <acehreli yahoo.com> writes:
On 2/12/25 12:55 PM, WhatMeWorry wrote:

 struct HexBoard(F,I)
 {
      this(F d, I r, I c) {}
      //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
 }

 void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier
 F and I
Would isInstanceOf be useful? (Which is actually optional.) It necessitated two aliases in the struct: void main() { struct HexBoard(F, I) { alias Float = F; alias Int = I; this(F d, I r, I c) {} } import std.traits : isInstanceOf; void displayHexBoard(HB)(HB h) if (isInstanceOf!(HexBoard, HB)) { pragma(msg, "The types are ", HB.Float, " and ", HB.Int); } auto h1 = HexBoard!(float,uint)(.25, 3, 7); displayHexBoard(h1); } Ali
Feb 12
prev sibling next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:
 ```
 void main()
 {

 struct HexBoard(F,I)
 {
     this(F d, I r, I c) {}
     //void displayHexBoard(HexBoard!(F,I) h) {}  // this 
 compiles fine!
 }

 void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined 
 identifier F and I


 auto h1 = HexBoard!(float,uint)(.25, 3, 7);
 auto h2 = HexBoard!(double,int)(.3, 5, 5);

 }


 Is there any clever way to move the method outside of a 
 templated block structure?  Or is this as good as it gets.

 I tried
 // Explicit instantiation for 'int' type
 //int add!(int, int);
 void displayHexBoardData(HexBoard2!(float,uint) h);  // 
 declaration

 but that just returns
 Error: declaration `displayHexBoard` is already defined
 onlineapp.d(10):        `function` `displayHexBoard` is defined 
 here
```d struct foo(T){} void bar(T)(foo!T){} unittest{ bar(foo!int()); bar(foo!float()); } ``` it can be inferred at the call site, but template arguments must still be declared
Feb 12
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:
 ```d
 void main()
 {

 struct HexBoard(F,I)
 {
     this(F d, I r, I c) {}
     //void displayHexBoard(HexBoard!(F,I) h) {}  // this 
 compiles fine!
 }

 void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined 
 identifier F and I


 auto h1 = HexBoard!(float,uint)(.25, 3, 7);
 auto h2 = HexBoard!(double,int)(.3, 5, 5);

 }
 ```

 Is there any clever way to move the method outside of a 
 templated block structure?  Or is this as good as it gets.
The problem is that the compiler doesn't know what F and I are. They are placeholders, but you didn't give them a definition. ```d void displayHexBoard(F, I)(HexBoard!(F,I) h) {} ``` -Steve
Feb 13
parent WhatMeWorry <kheaser gmail.com> writes:
Just wanted to thank everybody for their suggestions. Ali's code 
provided the breakthrough:

```d
import std.stdio;
void main()
{

struct HexBoard(F,I)
{
     this(F d, I r, I c) { diameter = d; rows = r; cols = c; }
     F diameter;
     I rows;
     I cols;
}

void displayHexBoard(HB)(HB h) {
     writeln(typeof(h.diameter).stringof);
     writeln(typeof(h.rows).stringof);
}

auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

displayHexBoard(h1);
displayHexBoard(h2);
}
```

which returned

float
uint
double
int

My problem was with the definition of void displayHexBoard(HB)(HB 
h) {} definition.

I kept futzing around with trying to insert HexBoard(F,I) into 
where HB is.  It is incredibly elegant how D can take h1 or h2 
and instantiate the template HB.
Feb 13
prev sibling parent bkoie <blaa some.com> writes:
On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:
 ```
 void main()
 {

 struct HexBoard(F,I)
 {
     this(F d, I r, I c) {}
     //void displayHexBoard(HexBoard!(F,I) h) {}  // this 
 compiles fine!
 }

 void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined 
 identifier F and I


 auto h1 = HexBoard!(float,uint)(.25, 3, 7);
 auto h2 = HexBoard!(double,int)(.3, 5, 5);

 }


 Is there any clever way to move the method outside of a 
 templated block structure?  Or is this as good as it gets.

 I tried
 // Explicit instantiation for 'int' type
 //int add!(int, int);
 void displayHexBoardData(HexBoard2!(float,uint) h);  // 
 declaration

 but that just returns
 Error: declaration `displayHexBoard` is already defined
 onlineapp.d(10):        `function` `displayHexBoard` is defined 
 here
```d import std.stdio; struct Foo(T, L) { T t; L l; } void display(T, L)(Foo!(T, L) f) { f.writeln; } alias FooIntD = Foo!(int, double); void main() { auto f = FooIntD(10, 20.3); f.display; } ```
Feb 13